精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

理論到實戰(zhàn),高可用架構(gòu)踩坑說明書

人工智能
目前消息發(fā)送,如果在消息體超過一定的大小的情況下,默認會開啟壓縮,但是在一些極限的情況下,仍然會出現(xiàn)消息體過大發(fā)送失敗的情況。

在構(gòu)建高可用系統(tǒng)時,開發(fā)者常常面臨應(yīng)用、數(shù)據(jù)庫、緩存、消息隊列等多維度的挑戰(zhàn)。本文結(jié)合京東真實技術(shù)場景,系統(tǒng)梳理高可用架構(gòu)實踐中常見的技術(shù)陷阱與解決方案,深入剖析每個技術(shù)組件的可用性保障要點。旨在為工程師提供一套踩坑說明書,幫助團隊在系統(tǒng)設(shè)計階段規(guī)避潛在風險,提升線上系統(tǒng)的穩(wěn)定性和容錯能力。

一、前言

通常情況下,我們在說一個事情之前,一定要把事情本身及其定義說得明明白白。那么,在對高可用架構(gòu)具體展開之前,我們先要好好說說,什么是高,怎么樣才算高,多高才算高,其次才是怎么才能做到高。

以系統(tǒng)建設(shè)場景為例,通常意義的高可用的標準至少要達到4個9的水準,即以一天為例,每天至少要保證少于8.64秒的故障產(chǎn)生。如果以更嚴格的5個9的水準來看,每天至少要保證少于近1秒的故障產(chǎn)生。達到了這樣的標準,才算高可用。

試問,假定我們的高可用標準為以上標準,捫心自問下,您能做到么?

筆者有自信,這個標準,很多團隊都做不到。那么,我們有沒有可以遵循的標準,指引我們往這個方向去前進和努力呢。我理解這個需要大家群策群力。筆者能力有限,水平一般。以下內(nèi)容,將基于筆者實際經(jīng)歷的一些常見的問題點及應(yīng)對方案進行展開,期望可以對大家的實際工作有一定的幫助作用。值得注意的是,避開這些問題點,是否可以達成高可用的標準不好說,但是很容易就走到高可用的反面。

在實際展開內(nèi)容之前,要達成高可用的標準,除常規(guī)的發(fā)布變更可能引發(fā)的風險和故障導(dǎo)致高可用標準時效外,我們還需要考慮線上在正常運行態(tài)下,也會存在“一切都不可靠,都會壞,且馬上就會壞”的情況,同時需考慮線上業(yè)務(wù)急速增長可平穩(wěn)支撐的解決方案。包括但不限于考慮容器、db、rpc依賴、redis緩存、mq消息等內(nèi)外部一切可能涉及的因素,考慮出現(xiàn)單點故障或大面積故障后業(yè)務(wù)會引發(fā)的變化,要求增加無死角的各類監(jiān)控(分鐘級和秒級),提前準備改造方案和預(yù)案。且要求對應(yīng)用程序的每一行代碼及依賴中間件的底層原理做到了如指掌,出現(xiàn)問題時才有可能做到快速定位分析、快速恢復(fù)、快速響應(yīng)。

以下內(nèi)容從常見的幾個涉及高可用的主題進行展開,每個主題都會下探一些常見的容易出現(xiàn)問題的場景及應(yīng)對方案。

二、應(yīng)用高可用

2.1 代碼故障

筆者把代碼故障分為兩類,一類是應(yīng)用類的,主要是應(yīng)用系統(tǒng)的開發(fā)人員引入的,此類問題較易發(fā)現(xiàn),定位難度雖有一定的差異,但是往往修復(fù)的方案相對可控,基本都可在應(yīng)用系統(tǒng)對應(yīng)的研發(fā)團隊內(nèi)閉環(huán)解決;另外一類是平臺類,主要包括依賴的包括但不限于JDK平臺,及各類依賴的開源代碼組件及內(nèi)部平臺組件,包括但不限于RPC框架、緩存框架等。

2.1.1 應(yīng)用類故障

主要涉及100%命中或大概率命中的業(yè)務(wù)場景,包括但不限于int溢出、字符長度溢出、除法為0、空指針異常等,此類場景在業(yè)務(wù)命中后,會極易導(dǎo)致此類場景的服務(wù)出現(xiàn)完全不可用的情況。

具體問題可分別描述如下,問題的排名及影響程度不分先后:

2.1.1.1 int溢出

以下圖為例,程序中執(zhí)行了Integer.parseInt的方法,一般情況下功能也沒有什么問題,但是如果出現(xiàn)需要轉(zhuǎn)換的值,超出了int的最大范圍,或者需要轉(zhuǎn)換的值,從數(shù)字類型變更調(diào)整為了字符串類型。兩種場景均會導(dǎo)致轉(zhuǎn)換失敗,如果此項轉(zhuǎn)換出現(xiàn)在主流程或者業(yè)務(wù)流量較大的場景,出現(xiàn)的問題影響及損失就不可計量了。

朋友們,如果你的代碼有這種情況,建議抓緊看看評估下,是否存在業(yè)務(wù)上的潛在風險?

圖片圖片

2.1.1.2 字符長度溢出

比較常見的問題有兩類,一類會造成應(yīng)用程序中的字符長度和數(shù)據(jù)庫的字符長度不匹配,出現(xiàn)后會出現(xiàn)數(shù)據(jù)庫無法保存的故障;一類是業(yè)務(wù)代碼中有對某些字符串有取固定某幾位的邏輯或者判定長度執(zhí)行特定邏輯,這種在上游沒有評估到位出現(xiàn)字符串的長度增加、減少,或者位置出現(xiàn)偏移的時候,也極易出現(xiàn)問題。

比如如下邏輯,識別倉是否為云倉業(yè)務(wù),執(zhí)行的邏輯為判定倉編號是否為9位數(shù)字,且首字母是否為8開頭。此類判定邏輯隨著時間變化,就比較容易產(chǎn)生問題。我們還是好好祈求下,期望業(yè)務(wù)范圍永遠在這個范圍里面,或者后續(xù)要調(diào)整的時候,有人可以識別到相關(guān)所有的依賴方。

圖片圖片

再比如如下邏輯,為京東里面依賴比較多的一個邏輯,即識別商品編號,來判定商品是否為普通圖書、臺版書、音像、電子書等業(yè)務(wù)。識別的邏輯為依賴商品的編號的號段來做邏輯,后來隨著商品的量級急劇膨脹,原來的號段邏輯不夠用了,相關(guān)的團隊不得不引入了一個外部的遠程的配置中心,并提供了獨立的sdk加載遠端的配置來實現(xiàn)復(fù)雜的號段邏輯。此類邏輯,也是高可用實踐中應(yīng)極力避免的場景。

圖片圖片

2.1.1.3 除法故障

在涉及到需要數(shù)學(xué)計算的場景里,這個問題比較常見。通常出現(xiàn)問題一般常見的故障為:1)未設(shè)置小數(shù)點及舍棄位規(guī)則 ,導(dǎo)致除法不能整除;2)業(yè)務(wù)上出現(xiàn)了除數(shù)為0的場景。

上述兩個場景在筆者的經(jīng)歷中多出現(xiàn)過,且出現(xiàn)問題后此類場景的業(yè)務(wù)也會出現(xiàn)完全不可用的情況。

Exception in thread "main" java.lang.ArithmeticException: Rounding necessary
    at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4179)
    at java.math.BigDecimal.needIncrement(BigDecimal.java:4386)
    at java.math.BigDecimal.divideAndRound(BigDecimal.java:4361)
    at java.math.BigDecimal.setScale(BigDecimal.java:2473)
    at java.math.BigDecimal.setScale(BigDecimal.java:2515)
2.1.1.4 代碼邏輯故障

這個分類里,會有各種五花八門的故障,而且這些故障只有你想不到,沒有你寫不出來的故障。曾經(jīng)有名產(chǎn)品走到一名研發(fā)跟前說,嘿,這么認真,又在寫bug呢。要破此局,需要大家共勉。

站在消費者的角度而言,一般而言,都期望下完單付完款后,可以盡快收到寶貝。那么技術(shù)上,就要求整體系統(tǒng)的鏈路維持高可用的狀態(tài),即支付后整體履約鏈路在日常情況下,可維持秒級平穩(wěn)且無毛刺出現(xiàn)的情況,基于更高的要求目標,在下游服務(wù)可能出現(xiàn)抖動的情況下,仍要保障整體下傳鏈路的通暢性,保障調(diào)用量級穩(wěn)定。

一般而言,此類復(fù)雜的履約鏈路,往往會依賴內(nèi)外部大量的RPC服務(wù),此類服務(wù)對應(yīng)的性能指標往往不一致,為應(yīng)對這種差異,往往會需要一個流程框架設(shè)置不同的業(yè)務(wù)流程節(jié)點來串聯(lián)相關(guān)的服務(wù),且此流程框架中需對有不同性能的業(yè)務(wù)節(jié)點提供差異化的服務(wù),也即對不同性能節(jié)點的業(yè)務(wù)節(jié)點配置差異化的線程池隊列。那么對此類業(yè)務(wù)場景,應(yīng)對高可用場景,至少應(yīng)有如下場景需重點考慮:

?目標

在待處理任務(wù)充足的情況下,每個業(yè)務(wù)線程都有足夠的待執(zhí)行任務(wù)需要處理,不出現(xiàn)線程饑餓的場景;

在待處理數(shù)據(jù)充足的情況下,主業(yè)務(wù)線程提交的待處理的任務(wù)數(shù)量過大,防止出現(xiàn)雪崩情況產(chǎn)生。

?優(yōu)化方案

業(yè)務(wù)主線程先獲取任務(wù)線程池緩沖區(qū)實時待處理任務(wù)數(shù)量,并動態(tài)決定是否需要提交待處理任務(wù),保障提交的待處理任務(wù)不會超過緩沖區(qū)大小且不會出現(xiàn)業(yè)務(wù)線程饑餓的情況,同時下傳流程框架移除CountDownLatch的邏輯限制,移除按批次處理的邏輯,使業(yè)務(wù)主線程提交一批待處理任務(wù)后,不會做任何等待,可以再次獲取系統(tǒng)執(zhí)行權(quán)。

?優(yōu)化效果

優(yōu)化前,下游服務(wù)抖動,引發(fā)調(diào)用量出現(xiàn)毛刺;優(yōu)化后,即使下游服務(wù)抖動,調(diào)用量依然是相對穩(wěn)定。

2.1.2 平臺類故障

此類故障一般都隱藏得較深,不易發(fā)現(xiàn)。而且及時發(fā)現(xiàn)了,一般平臺的響應(yīng)速度均會較快,可在新的版本中進行修復(fù),應(yīng)用開發(fā)人員將對應(yīng)的版本進行升級即可完成問題修復(fù)。常見出現(xiàn)的問題是應(yīng)用開發(fā)人員使用了一些存在問題的低版本,此處的難點在于如何對涉及的依賴平臺組件完成平穩(wěn)無縫升級,這個問題及應(yīng)對的方案留給大家。在實操中,我們也可以發(fā)現(xiàn),即使是大名鼎鼎的JDK,這個所有人賴以生存的基礎(chǔ)底座,都有一些極其低級的bug。

需要說明的是,下方的較多代碼bug或故障,較多情況并不會對實際業(yè)務(wù)造成影響,但是以高可用的標準來要求的話,還是有必要多多關(guān)注,早日完成問題修復(fù),不留潛在風險。

以下以筆者曾經(jīng)遇到的平臺類故障進行展開描述,問題排名及影響不分先后。

2.1.2.1 JDK故障--數(shù)組越界

此數(shù)組越界問題是在大促備戰(zhàn)中發(fā)現(xiàn)。需要注意的是,此問題實際不影響業(yè)務(wù)功能,因為JDK對此類異常進行了捕獲并處理,但是應(yīng)用系統(tǒng)中因為此問題會導(dǎo)致潛在的高頻拋出和捕獲異常,而眾所周知,高頻拋出異常對應(yīng)用服務(wù)器的壓力及GC耗時均有較大的影響。

需要說明的,下方復(fù)現(xiàn)問題的代碼,您在控制臺默認啟動試運行的時候,是不會出現(xiàn)下方的堆棧信息的。那么什么時候會出現(xiàn)這個異常呢?簡單,我們在JDK的源碼類SignatureParser對應(yīng)的異常代碼里面增加對應(yīng)的斷點即可。通過查閱資料,我們發(fā)現(xiàn)JDK在8u311的版本修復(fù)了這個bug,相關(guān)的bug鏈接為:https://bugs.openjdk.org/browse/JDK-8035424,實際代碼fix的鏈接為:https://hg.openjdk.org/jdk8u/jdk8u/jdk/rev/2e292618f87a

那么這個問題什么時候會出現(xiàn),筆者可以很明確的說:很多場景都會出現(xiàn),最簡單的場景即為復(fù)現(xiàn)代碼中使用json解析的場景即會出現(xiàn)。

那么這個問題,應(yīng)該如何修復(fù)呢?從上方的信息可以看到,JDK在8u311版本中已完成問題修復(fù),那么我們直接升級對應(yīng)的版本即可。看起來很簡單,對么?

但是實際有這么簡單么?那當然不會,否則我也不會寫到這里了。筆者從部署平臺詢遍了所有可使用的鏡像版本,里面涉及到JDK8的版本,沒有一個版本高于8u311版本,這也就意味著,此問題,在所有使用JDK8版本的應(yīng)用里面,都有此類潛在隱患。想想這個問題,是不是覺得很震撼,很奇妙?

問題堆棧為:

"main@1" prio=5 tid=0x1 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
      at java.lang.ArrayIndexOutOfBoundsException.<init>(ArrayIndexOutOfBoundsException.java:65)
      at sun.reflect.generics.parser.SignatureParser.current(SignatureParser.java:95)
      at sun.reflect.generics.parser.SignatureParser.parseSuperInterfaces(SignatureParser.java:559)
      at sun.reflect.generics.parser.SignatureParser.parseClassSignature(SignatureParser.java:214)
      at sun.reflect.generics.parser.SignatureParser.parseClassSig(SignatureParser.java:156)
      at sun.reflect.generics.repository.ClassRepository.parse(ClassRepository.java:57)
      at sun.reflect.generics.repository.ClassRepository.parse(ClassRepository.java:41)
      at sun.reflect.generics.repository.AbstractRepository.<init>(AbstractRepository.java:74)
      at sun.reflect.generics.repository.GenericDeclRepository.<init>(GenericDeclRepository.java:49)
      at sun.reflect.generics.repository.ClassRepository.<init>(ClassRepository.java:53)
      at sun.reflect.generics.repository.ClassRepository.make(ClassRepository.java:70)
      at sun.reflect.generics.repository.ClassRepository.<clinit>(ClassRepository.java:43)
      at java.lang.Class.getGenericInfo(Class.java:2548)
      at java.lang.Class.getGenericSuperclass(Class.java:765)
      at org.codehaus.jackson.type.TypeReference.<init>(TypeReference.java:33)

復(fù)現(xiàn)問題的代碼為:

public class ATest {
    public static void main(String[] args) {
        String str = "{\"aa\":\"bb\"}";
        try {
            Object o = JacksonMapper.getInstance()
                    .readValue(str, new TypeReference<Map<String, String>>() {
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

JDK的修復(fù)方式如下所示,修復(fù)的邏輯可以看到也比較簡單,將原來粗暴的異常修改為前置邏輯判定即可:

圖片圖片

2.1.2.1 RPC框架故障--找不到方法異常

JSF目前為京東平臺內(nèi)部使用的RPC框架,此技術(shù)框架目前提供2種交互協(xié)議:msgpack和hessian。容易出現(xiàn)問題導(dǎo)致存在高可用隱患的場景為:服務(wù)提供方和服務(wù)依賴方,交互的時候使用的是msgpack的協(xié)議,且交互的輸入輸出有使用BigDecimal的話,通過火焰圖等性能分析工具分析應(yīng)用程序運行時狀態(tài),我們會發(fā)現(xiàn)火焰圖中有大量的無法找到方法的異常。

那么這個方案有沒有解決方案呢?有的,按平臺建議,我們將RPC框架的協(xié)議,從默認的msgpack,切換為hessian即可。那么除了這個方案,JSF在msgpack協(xié)議下的這個bug還有沒有其他的解決方案呢。很遺憾的知悉大家,沒有了。那么切換為hessian有沒有什么潛在風險和隱患呢?應(yīng)該還是有一些的,詳細可以參見JSF的文檔說明,另要說明一點,從msgpack協(xié)議,切換為hessian協(xié)議,默認是會有少許的性能損耗的。

火焰圖異常信息為:

圖片圖片

可穩(wěn)定復(fù)現(xiàn)的demo代碼如下所示,此處還需要再強調(diào)一點:在控制臺默認啟動試運行的時候,是不會出現(xiàn)下方的堆棧信息的。要能發(fā)現(xiàn)并定位出這個異常,需要我們在JDK的源碼類對應(yīng)的異常代碼里面增加對應(yīng)的斷點即可。

import com.jd.jsf.gd.codec.msgpack.MsgpackDecoder;
import com.jd.jsf.gd.codec.msgpack.MsgpackEncoder;
import java.math.BigDecimal;
public class ATest {
    public static void main(String[] args) {
        MsgpackEncoder msgpackEncoder = new MsgpackEncoder();
        PayDetailVo payDetailVo = new PayDetailVo();
        payDetailVo.setCurrencyPrice(BigDecimal.TEN);
        byte[] encode = msgpackEncoder.encode(payDetailVo);
        MsgpackDecoder msgpackDecoder = new MsgpackDecoder();
        PayDetailVo decode = (PayDetailVo) msgpackDecoder.decode(encode, PayDetailVo.class);
        System.out.println(decode.getCurrencyPrice());
    }
    private static class PayDetailVo {
        private BigDecimal currencyPrice;
        public BigDecimal getCurrencyPrice() {
            return currencyPrice;
        }
        public void setCurrencyPrice(BigDecimal currencyPrice) {
            this.currencyPrice = currencyPrice;
        }
    }
}

此處再多說一點,對這個問題產(chǎn)生的原因再詳細展開下。從上方火焰圖的信息可以看到,實際出現(xiàn)的異常是獲取BigDecimal的構(gòu)造函數(shù),并且是BigDecimal的默認的構(gòu)造函數(shù)時,出現(xiàn)的無法找不到類的異常。但是您猜猜BigDecimal有沒有默認的構(gòu)造函數(shù)呢?答案是真沒有。

詳細參見下方截圖:

圖片圖片

2.1.2.1 緩存框架故障--緩沖區(qū)溢出異常

jimdb為京東內(nèi)部可和redis對應(yīng)的緩存技術(shù)框架。這個問題出現(xiàn)的場景為,所有低于2.1.12(23年8月份發(fā)布)版本的jimdb,特別是之前強烈大家推薦升級的2.2.8-shade版本,在操作任意讀、寫redis命令時,均可穩(wěn)定出現(xiàn)這個異常。

需要說明的是,此類異常,也和上面介紹的異常類似,常規(guī)方式無法看出來,只有對性能及服務(wù)高可用有極致追求,通過壓力測試及火焰圖等工具才能比較快的定位出來。

那么,您能看看,您自己負責的系統(tǒng),使用的jimdb版本是什么版本么。

詳細的異常火焰圖如下:

圖片圖片

具體產(chǎn)生的異常代碼如下所示:

圖片圖片

從上方的信息,比較容易看到是SDK在定義緩沖區(qū)的大小時長度不足預(yù)期,往緩沖區(qū)放的時候出現(xiàn)了溢出異常,但是SDK的代碼捕獲了這類異常,同時將緩沖區(qū)的大小擴大一倍類解決問題。還是那句話,您要問業(yè)務(wù)功能上有沒有問題,那當然是沒有。但是您要問這種寫法真的好么?那筆者覺得這真是一個讓人可以深思的好問題。

SDK對這個問題的解決方案也很粗暴,上方JDK的處理方式有異曲同工之秒,修復(fù)后的代碼詳細可參加下方的截圖:

圖片圖片

2.1.2.1 緩存框架故障--空指針異常

這個問題出現(xiàn)的場景為發(fā)現(xiàn)上方的緩沖區(qū)異常后,我們應(yīng)用開發(fā)人員抓緊升級到2025年7月18號升級的最新版版本2.3.1-HOTFIX-T2,繼續(xù)開啟壓測和火焰圖后,發(fā)現(xiàn)應(yīng)用中存在空指針異常的情況出現(xiàn)。還是說明一下,這個不影響業(yè)務(wù)功能,只是對性能有一定的損耗,具體損耗會依據(jù)應(yīng)用系統(tǒng)的不同略有差異。

這個問題最后定位下來,是應(yīng)用里面的一個jar(titan-profiler-sdk)較為老舊,新版本的緩存SDK依賴的新版的jar功能,最終在運行態(tài)會出現(xiàn)本案例的空指針異常。

這個問題的火焰圖信息如下:

圖片圖片

2.2 單容器故障

這一點想要描述的是線上單點或少批量的機器故障。在一般的認知里面,線上服務(wù)均為集群部署模式,單點或者少量故障,理論上不會對服務(wù)的可用性造成太大的影響。但是,真的是這樣么?

以筆者的經(jīng)驗來看,單容易故障不造成太大的問題,一般出現(xiàn)在業(yè)務(wù)場景不太復(fù)雜的場景。以下以筆者的實操經(jīng)歷,從4個方面來進行詳細展開,描述因單容器故障造成實際影響的案例:

1)線上服務(wù)為web類服務(wù):此類場景,往往在域名控制臺中心綁定了域名和容器IP,假定某一臺或者某幾臺容器出現(xiàn)故障無法訪問,在沒有人工介入的情況下,考慮下此域名的業(yè)務(wù)使用方,是否會出現(xiàn)間歇性不能訪問的情況?是否有些工具可以做到自動切換,但是切換周期有多?以及是否所有的業(yè)務(wù)場景均配置了自動切換功能呢?這個問題,留給大家去思考

2)線上服務(wù)為RPC提供方服務(wù):您服務(wù)對應(yīng)的容器異常宕機了,您收到的一般為容器故障或網(wǎng)絡(luò)連通性異常等告警。但是RPC的接口依賴方,其對應(yīng)的服務(wù)可用率在問題出現(xiàn)期間,是否會出現(xiàn)可用率下跌的問題,及多長時間會自動恢復(fù)?這個問題,也留給大家去思考

3)線上服務(wù)為MQ消費服務(wù):MQ的工作原理,在下文MQ高可用章節(jié)會詳細展開,此處簡單說一下:單機故障后,在MQ客戶度沒有較好的優(yōu)雅關(guān)機的情況下,故障的那一瞬間,假定應(yīng)用程序已從MQ的服務(wù)端拿到了較多的消息在本地進行消費,沒有來得及給MQ服務(wù)端進行應(yīng)答的時候,同時假定MQ服務(wù)端的超時時間設(shè)置比較長的情況下,會出現(xiàn)MQ服務(wù)端的消息短時間內(nèi)出現(xiàn)部分鎖死無法消費,進而出現(xiàn)消息短時間內(nèi)積壓的情況出現(xiàn)。您是否遇到過類似的問題?

4)線上服務(wù)為流程框架調(diào)度類服務(wù):此類服務(wù)一般會有一個流程管理框架,在流程服務(wù)本身依賴的容器故障,或者流程服務(wù)依賴的服務(wù)出現(xiàn)故障時,系統(tǒng)不同的設(shè)計,會有不同的故障反應(yīng)。

以流程服務(wù)本身依賴的容器故障為例,嚴謹?shù)牧鞒炭蚣苄璞U狭鞒烫幚淼臄?shù)據(jù)能夠被及時調(diào)度起來,否則極易出現(xiàn)任務(wù)執(zhí)行延遲導(dǎo)致業(yè)務(wù)同步延遲的情況,那么怎么定義及時調(diào)度起來,如何及時調(diào)度起來呢?這個問題,同樣留給大家去思考。

再以流程服務(wù)依賴的服務(wù)的容器出現(xiàn)故障為例,嚴謹?shù)牧鞒炭蚣芤M量降低依賴服務(wù)的問題造成框架本身的調(diào)度問題,包括但不限于引發(fā)調(diào)度框架的業(yè)務(wù)量級出現(xiàn)突增或者突降的情況,在保障業(yè)務(wù)平穩(wěn)運行的情況下,還要對依賴的服務(wù)做好一定的保護措施,包括但不限于增加一定的措施,防止依賴的服務(wù)短時間內(nèi)調(diào)用量級過大引發(fā)依賴服務(wù)出現(xiàn)雪崩的情況出現(xiàn)。

2.3 機房故障

這類問題不太常見,但是一旦出現(xiàn),就是致命的影響,出現(xiàn)后必定會出現(xiàn)各類人仰馬翻的情況。可以設(shè)想,一旦某一個機房整體出現(xiàn)故障,那么我們可以簡單分析下哪些業(yè)務(wù)會產(chǎn)生影響。

1)流量入口:可以觀察到流量入口對應(yīng)的機房出現(xiàn)了故障,對應(yīng)的流量會出現(xiàn)短時間無法訪問的異常,這時候比較快的方式是摘除對應(yīng)的流量入口,需要考驗的就是定位問題的速度和摘除時的手速了。

2)各類RPC服務(wù):各類垂直調(diào)用的RPC服務(wù),在流量入口摘除整體機房后,理論上相關(guān)的機房的流量就會自動消除,看起來好像沒有什么業(yè)務(wù)影響。但是這個只是理論上的,目前線上還存在一些應(yīng)用沒有做手動或自動的垂直分組隔離,同時也會有一些任務(wù)會出現(xiàn)流量逃逸的情況出現(xiàn)。其他條線的業(yè)務(wù),如果流量入口沒有控制好,那么至少故障機房的影響就需要好好評估下了。

3)各類MQ服務(wù):這個就要依賴MQ的部署機房架構(gòu)了。如果MQ對應(yīng)的服務(wù)端部署在多個機房,理論上發(fā)送端的可用率就很難做到100%。MQ平臺是否可以做到發(fā)送時自動摘流,以筆者有限的經(jīng)驗來看,現(xiàn)階段應(yīng)該還不太行。

4)各類DB服務(wù):這個就更是一團亂麻了。不展開分析了。

5)緩存服務(wù):不展開分析了。

2.4 GC故障

市面上常常有一種說法,說面試造火箭,入廠擰螺絲。指的一般都是各類八股文的考題,其中GC在里面居多。從筆者的觀察來看,在較多的非核心系統(tǒng)里面,GC往往不為大家所關(guān)注。即使在較核心的系統(tǒng)里,GC的問題也不是能引起所有角色的關(guān)注。哪怕是在筆者寫文章的此時此刻,線上某個團隊的某一個0級核心服務(wù)對應(yīng)的TP999數(shù)據(jù)也會出現(xiàn)隨著時間的延長,會出現(xiàn)性能數(shù)據(jù)逐步緩慢攀升;并隨著全量發(fā)布后,性能出現(xiàn)急劇回落至正常水平的情況。即使是我們團隊,GC的耗時較高待優(yōu)化的系統(tǒng),在清單里面的也有較多。

下文以我們實際遇到的2個具體的優(yōu)化案例進行展開,期望對大家有一定的幫助作用。

?gc調(diào)優(yōu)--連接池調(diào)優(yōu)

?表現(xiàn):在某壓測過程中,某一類接單一直卡在5000qps上不去,上游應(yīng)用調(diào)用接單服務(wù)tp99超350ms已上,但是接單服務(wù)應(yīng)用的吞吐率上不去。

?原因:1)通過JVM監(jiān)控發(fā)現(xiàn)youngGC頻繁且峰值耗時在400ms左右,并未觸發(fā)fullGC。經(jīng)分析當前容器是4C8G,jvm配置gc并行處理線程數(shù)是(ParallelGCThreads=4),存在垃圾回收線程不夠的情況。2)數(shù)據(jù)庫連接池參數(shù)配置不合理,導(dǎo)致頻繁創(chuàng)建和回收連接池,整體gc的耗時在400毫秒上下浮動。

?舉措:1)升級到容器規(guī)格由4C8G升級到8C16G,同時調(diào)整JVM堆內(nèi)存、新生代內(nèi)存大小,調(diào)整GC并行處理線程數(shù)到8(ParallelGCThreads=8)。youngGC時長問題解決,youngGC耗時在30ms以下;2)優(yōu)化連接池參數(shù)

結(jié)果:在沒有其他優(yōu)化的前提下,優(yōu)化前平均耗時176.7ms,優(yōu)化后平均耗時17.2ms。

?GC調(diào)優(yōu)--字符串緩存關(guān)閉

?表現(xiàn):在壓測過程中,持續(xù)的高流量試跑導(dǎo)致部分實例在過程出現(xiàn)FGC情況,引發(fā)服務(wù)對應(yīng)的TP99段時間內(nèi)飆高,進而導(dǎo)致整體調(diào)用量級出現(xiàn)毛刺和掉坑。同時觀察發(fā)現(xiàn)的堆內(nèi)存時間隨著時間的推移穩(wěn)定增長,直到觸發(fā)一次fullgc。

?原因:拆分中使用了Jackson1進行json序列化,其中會用 String.intern() 來做字符串的緩存,這樣重復(fù)的字符串就可以只存一份了,因為返回的 Json 里的 Key 是 一個Java生成的UUID,這個key幾乎不會重復(fù),所以導(dǎo)致緩存池里的字符串越積越多,直到GC的時候才會回收。

?舉措:通過代碼關(guān)閉jackson中的字符串緩存,問題解決。此問題還有沒有其他好的解決方案,也留給大家去思考。

三、db高可用

3.1 JED查詢單分片故障

需要說明的是,JED為京東內(nèi)部可和mysql對應(yīng)的一類數(shù)據(jù)庫。和傳統(tǒng)mysql不同,JED自帶路由網(wǎng)關(guān),期望將底層的mysql實現(xiàn)對研發(fā)透明,業(yè)務(wù)邏輯和JED交互的時,若SQL中帶有分片hash鍵,則網(wǎng)關(guān)會計算并路由hash到對應(yīng)的mysql實例上;若SQL中不帶有分片hash鍵,則網(wǎng)關(guān)會將請求發(fā)送給所有的mysql實例,并在網(wǎng)關(guān)層聚合返回結(jié)果。

此處主要要強調(diào)的是,我們要理解JED的工作原理,按一般邏輯,我們和JED交互的時候,最佳實踐是SQL中帶著分片鍵,不然會引發(fā)跨片查詢。跨片查詢存在2類弊端:1)因為是對所有的分片進行并發(fā)查詢,最后完成數(shù)據(jù)的歸集,那么性能會存在一定程度的損耗(損耗程度取決于SQL的復(fù)雜度);2)任意一個mysql分片宕機,并發(fā)查詢的時候必定會命中這個壞的分片,最終會出現(xiàn)查詢結(jié)果完全不可用場景。

3.2 JED事務(wù)故障

業(yè)務(wù)邏輯開啟事務(wù)時,默認會使用select @@session.tx_read_only語句,此語句一是會影響性能;二是此語句在JED場景下,因為此sql并沒有帶分片鍵,會隨機選擇一個分片進行查詢掃描,若很不巧,掃描的分片整好是壞的那臺機器,可能會加大失敗的概率。也即假定我們線上有10個JED的分片,若現(xiàn)在某一個分片出現(xiàn)了故障,那么按推論,故障的比例應(yīng)該是百分之十,但是因為此項事務(wù)機制導(dǎo)致隨機掃分片,會將故障的比例升高擴大至20%。

解決方案:通過jdbcurl上配置useLocalSessionState = true

3.3 JED全局唯一鍵故障

jed如果使用全局自增id,在沒有特殊訴求的情況下,會默認使用第一個分片,即當?shù)谝粋€分片宕機時,按預(yù)期是只有一個分片對應(yīng)的業(yè)務(wù)出現(xiàn)故障,但是這種場景下,最后的結(jié)果與預(yù)期不符,所有的insert均會全部失敗。

3.4 慢sql故障

這個比較好理解,不詳細展開

3.5 大事務(wù)故障

在各個系統(tǒng)設(shè)計中,因為歷史架構(gòu)設(shè)計原因,存在較多大事務(wù),在業(yè)務(wù)量級較小的情況下,此種用法尚沒有太多問題,但是一旦上強度業(yè)務(wù)量級和并發(fā)上來,此種設(shè)計機制對數(shù)據(jù)庫會形成較大的壓力,導(dǎo)致數(shù)據(jù)庫對應(yīng)的qps無法提升,從而影響整體服務(wù)的吞吐。

以履約的其中一個系統(tǒng)舉例,歷史上利用接單防重表的事務(wù)來保障2個RPC寫操作的一致性,該大事務(wù)會導(dǎo)致DB鎖等待,吞吐量上不去。雖然可以通過擴JED分片的機制來減少單分片的鎖等待,提升吞吐量,但還是存在架構(gòu)不合理,性能瓶頸的問題。

解決方案:對防重表增加狀態(tài)機制,通過一次insert和一次update操作保障2個RPC的寫,避免使用insert大事務(wù)。

3.6 流量放大故障

所謂流量放大,以訂單條線為例,假定處理一個訂單,正常業(yè)務(wù)需對應(yīng)10條讀寫sql語句,但是通過監(jiān)控發(fā)現(xiàn)存在一個訂單對應(yīng)10倍到100倍的sql情況產(chǎn)生。

這個問題,比較致命,也比較隱藏,在db沒有壓力瓶頸的情況下,不易發(fā)現(xiàn);在db有壓力瓶頸的情況下,要么不好發(fā)現(xiàn),要么發(fā)現(xiàn)后來不及調(diào)整。建議大家多關(guān)注監(jiān)控,對此類流量放大的情況,提前完成治理工作。

3.7 db字段長度不足故障

這種問題,一般出現(xiàn)在此字段上下游沒有對齊的情況。在業(yè)務(wù)發(fā)展初期,或者在團隊規(guī)模較小的時候,大家的字段長度都保持類似,但是隨著業(yè)務(wù)不斷發(fā)展,原來的字段長度已不足以支撐業(yè)務(wù)發(fā)展,上游將字段提前完成了擴容,但是并沒有好的工具可以梳理到下游的影響,導(dǎo)致下游遺漏了修改動作。在某一個夜黑風高的夜晚,終于出現(xiàn)了寫入db失敗的異常,最終引發(fā)業(yè)務(wù)故障。

3.8 單集群存儲不足故障

此處想強調(diào)的是存儲資源不足的情況。試問下各位,您能說清楚您負責的系統(tǒng),考慮目前的業(yè)務(wù)增長趨勢保持不變、增長趨勢翻10倍、增長趨勢翻100倍的場景下,您負責的db存儲,還可以支撐多久?如果支撐時間很短,必然說只有一個月的話,應(yīng)該有什么解決方案呢?這個問題,留給大家。

較多系統(tǒng)存在單庫或者JED容量已經(jīng)無法滿足業(yè)務(wù)增長的情況,在小流量的情況下,數(shù)據(jù)庫不是瓶頸,一旦流量激增,一個跨分片的SQL或者一個JED單片的故障,都將引發(fā)一場災(zāi)難。但是從傳統(tǒng)的mysql升級到j(luò)ed,包括升級到目前的DongDal組件,還是有一些注意事項需要大家多多關(guān)注:

?check語法是否支持:傳統(tǒng)mysql升級至JED時,check原有SQL中使用的語法在JED是否支持

?關(guān)注網(wǎng)關(guān)性能:升級JED時需關(guān)注負載均衡、網(wǎng)關(guān)的配置及性能波動。例如,JED的負載均衡、網(wǎng)關(guān)、分片都在匯天機房,如果匯天網(wǎng)段出現(xiàn)網(wǎng)絡(luò)不問題,TCP重傳數(shù)高的問題。可能會導(dǎo)致JED查詢、修改等語句執(zhí)行時間TP99升高。

?低峰期執(zhí)行DDL:執(zhí)行對數(shù)據(jù)庫執(zhí)行表結(jié)構(gòu)修改時,需要觀察每個分片的QPS(包括總QPS、read QPS、write QPS),在QPS的低峰時,且各分片QPS均勻無異常波動,才可以執(zhí)行表結(jié)構(gòu)修改。黃金流程鏈路建議凌晨2點后,同時需要如果有大數(shù)據(jù)抽數(shù)任務(wù),也需要提前做協(xié)調(diào)和溝通,避免業(yè)務(wù)系統(tǒng)變更引發(fā)大數(shù)據(jù)側(cè)的事故。

?避免跨片查詢:SQL中最好都帶上增加分片鍵,不然會引發(fā)跨片查詢,跨片查詢的性能會存在一定程度的損耗(損耗程度取決于SQL的復(fù)雜度)

?增加數(shù)據(jù)庫連接池的探活配置:客戶端到JED網(wǎng)關(guān)之間還有LB作為網(wǎng)絡(luò)代理,LB會主動清理空閑10分鐘及以上的連接。需要業(yè)務(wù)側(cè)連接池進行保活或探測連接,否則LB會把連接殺掉,再次使用時會出現(xiàn)異常。

?事務(wù)30秒超時限制:為了提升JED網(wǎng)關(guān)連接池的使用效率,保護底層MySQL實例,針對事務(wù)有30秒的超時限制。

?JED單實例安全水位線:磁盤使用過大:進行數(shù)據(jù)歸檔或結(jié)轉(zhuǎn);QPS過大:增加緩存

類型

安全

中危

高危

磁盤使用(非歸檔類)

<=2T

>2T&<4T

>4T

QPS

<=1萬

>1萬&<=3萬

>3萬

四、Redis高可用

4.1 JIMDB超時和熱key治理

JIMDB超時時間設(shè)置若不合理,在JIMDB故障時較容易出現(xiàn)無法快速熔斷,阻塞業(yè)務(wù)的情況,同時若應(yīng)用中存在單點熱key的存在,如果該熱key正好在故障的JIMDB分片上,就比較容易造成故障產(chǎn)生。

?超時時間治理:根據(jù)歷史上的業(yè)務(wù)監(jiān)控數(shù)據(jù),我們應(yīng)將JIMDB的超時時間設(shè)置在合理的閾值,實現(xiàn)業(yè)務(wù)快速熔斷。調(diào)整配置的讀、寫命令超時時間以及新建連接超時時間。同時注意 JAVA-SDK版本在 2.1.15及以下版本SDK不支持讀寫超時分開控制;如果應(yīng)用使用了這些SDK,所有的讀寫請求超時會統(tǒng)一使用寫命令超時參數(shù)。另外,新建鏈接超時過大,可能導(dǎo)致無法快速釋放鏈接,進而放大單片故障對業(yè)務(wù)系統(tǒng)的影響

?熱key治理:需要評估該熱key的實現(xiàn)規(guī)則是否合理,尤其避免key為固定常量的寫法

4.2 JIMDB高危命令治理

在使用jimdb時,為了使多個原子操作保持一致性,通常會使用lua腳本將多個原子操作打包處理。jimdb提供的上傳lua腳本方法scriptLoad,會掃描所有節(jié)點并上傳,當有一個節(jié)點不可用時,上述上傳動作會阻塞其他正常節(jié)點的上傳,直至異常節(jié)點超時返回或異常節(jié)點主從切換完成正常返回。該過程會影響正常分片的使用。

圖片圖片

?減少lua腳本上傳:建議在初始化時執(zhí)行一次lua腳本上傳。jimdb內(nèi)部在主從節(jié)點也分別存儲了腳本,在發(fā)生主從切換時,可以不用再次上傳。

?針對特定異常補充上傳:當節(jié)點不可用或擴分片的場景捕獲該異常ScriptNotFoundException,重新上傳lua腳本。

五、MQ高可用

MQ在各個應(yīng)用場景中,被當做一個神兵利器來使用,但是通過這些年的觀察,較多人對其底層原理和各類注意事項并沒有太清晰的認知,此處以JMQ(Jingdong Message Queue)京東自研的低延遲、高并發(fā)、高可用、高可靠的分布式消息流處理平臺為案例,結(jié)合筆者曾經(jīng)遇到的問題展開描述,期望對大家有所幫助。

5.1 JMQ應(yīng)答超時故障

?表現(xiàn):某場景消費消息監(jiān)控在2025-06-24的14:17:10至14:19:03有明顯下降

?原因:上線中消費實例拉取消息后,直接關(guān)閉應(yīng)用tomcat實例,客戶端獲取到的隊列partition的占用就不會釋放,積壓2分鐘內(nèi)消息的積壓持續(xù)增長,2分鐘后又快速消費掉了。

需說明的是:以MQ消費存在的鎖消息及滑動窗口逐批消費的概念及原理,基于MQ的鏈路要想做到秒級無延遲無抖動,極難做到。

以下再舉一個較為形象的例子,來展開說明下MQ的發(fā)送及消費原理:

圖片圖片

與redis、jimdb這種內(nèi)存式存儲的存儲中間件不同,MQ的存儲其實是基于連續(xù)的文件來存儲的,這一點認知特別重要。

以上方的消費示意圖來看,MQ概念中的Broker可以近似認為是各個單獨的容器,隊列則是各個容器中不同的存儲文件,可以簡單認為在一個Broker中每個隊列會對應(yīng)不同的文件,MQ的寫入方會順序?qū)懭胛募琈Q的消費方則會順序讀取文件。

可以觀測到,如果業(yè)務(wù)量級比較大的情況下,消息的消費速度主要首先于以下幾個因素:單個消息消費的耗時、消息Broker的數(shù)量、消息隊列的個數(shù)。可以看到單個消息消費的耗時越小,則消費速度越快;消息Broker的數(shù)量、消息隊列的個數(shù)越大,則消費的速度越快。這也是為什么不同的業(yè)務(wù)場景下,MQ團隊會給我們設(shè)置差異化的消息Broker的數(shù)量、消息隊列的個數(shù)的最主要的原因。

從上方的示意圖也可以看到,在一般的情況下,每個隊列的寫入和讀取都是順序的,以寫入為例,只有新的消息寫入成功后,下一條消息才可以在這個隊列繼續(xù)寫入;以消費為例,只有排在隊頭的消息被成功消費,隊頭后面的消息才有被消費的機會。一般而言,寫入的速度取決于文件存儲磁盤的速度,一般沒有瓶頸;往往有瓶頸的為消費的速度。消費的速度跟不上的情況下,MQ上觀測到的就是會出現(xiàn)消息積壓,業(yè)務(wù)無法及時處理的情況。

這種情況,因為瓶頸點在MQ服務(wù)器,往往增加應(yīng)用服務(wù)器的數(shù)量,并不會有好的改善效果。那么在受限于機器資源等原因?qū)е孪roker的數(shù)量、消息隊列的個數(shù)無法持續(xù)擴大的情況下,MQ團隊提供了一個方案可以進一步加速消費的速度。也即在每個隊列的維度上增加一定的并發(fā),實現(xiàn)原理為使用了滑動窗口的機制,即為每個隊列再虛擬出30個虛擬可并行執(zhí)行的隊列,假定每個隊列的并發(fā)數(shù)是30,則消費方理論上可以同時從這30個虛擬隊列中拿到消息。此種方式變相的相當于了擴大Broker或者隊列的數(shù)量,也是加速消費的比較好的實踐。

那么對這一點,有沒有什么注意的事項呢。當然有。問題點就在這個滑動窗口的機制和原理里。滑動窗口虛擬出30個并行的隊列,繼續(xù)往下滑的前提條件是這30個隊列的每一個消息都被成功消費了,請注意,這里指的是每一條消息都被成功消費了。那么很容易就可以觀測到,消息消費基本是分批處理的機制,每個批次的數(shù)量取決于并行的大小,假定批次中的任意一個消息沒有得到及時應(yīng)答,那么這個隊列后的所有消息,仍然不會被消費到,業(yè)務(wù)上觀測到的就是這個隊列的消息又會出現(xiàn)積壓了。

那么什么時候回出現(xiàn)沒有及時應(yīng)答的情況呢,這個就比較多了,在應(yīng)用服務(wù)器異常宕機、應(yīng)用服務(wù)器對應(yīng)的依賴服務(wù)出現(xiàn)劇烈抖動、少量抖動時,MQ服務(wù)器都不能快速收到消息成功消費的應(yīng)答,也即此隊列的消息有極大的概率會出現(xiàn)被堵住的情況。

這個問題有好的解決方案么?在筆者看來,并沒有太好的解決方案,設(shè)置MQ的默認應(yīng)答時長可以一定程度減緩這個問題的發(fā)生,但是本質(zhì)上無法解決。在考慮高并發(fā)無延遲的情況下,采用MQ的技術(shù)方案一定要慎重。另外,MQ本身設(shè)定的技術(shù)應(yīng)用場景就是為了上下游解耦使用,應(yīng)對的一個場景為削峰填谷,應(yīng)對的是上下游速率較大可能不一致的情況,或應(yīng)對的場景為有多個下游依賴方,指望通過服務(wù)的方式通知所有下游不太現(xiàn)實的情況。

有關(guān)消費的原理,再展開描述如下:

圖片圖片

存儲:消息是存儲在partition里的,是一條挨著一條存儲的。如上圖的“服務(wù)端”。

消費:在客戶端拉取消息時,服務(wù)端會從消費位置(如上圖的“消費位置”)開始,拿一批消息返回給客戶端。客戶端A拉走一批消息后,服務(wù)端要避免,這批消息被另外一個客戶端拉走,所以在客戶端確認結(jié)果之前,該partition會一直被客戶端A占用,保證不會被其他客戶端再拉取消息。客戶端成功消費這些消息后,會給客戶端確認,服務(wù)端收到確認后,會移動消費位置,并釋放占用(鎖),等待下次拉取。

客戶端會有一個消費線程不停的在循環(huán)執(zhí)行:拉取消息 -- > 執(zhí)行消費邏輯 --> 確認結(jié)果 -- > 拉取消息 ………… 這個流程。

當服務(wù)端1號partition的消息被客戶端A拉走后,為了避免這批消息被重復(fù)消費,服務(wù)端會記錄:1號partition正在被客戶端A占用,避免被其他客戶端重復(fù)拉走消息。

這個時候,如果客戶端A突然假死(或者其他異常場景),那客戶端A對1號partition的占用就不會釋放。占用不釋放,1號partition的消息就永遠不會被其他客戶端消費到。為了避免這種情況,服務(wù)端會有一個占用超時的概念,即如果客戶端一個比較長的時間內(nèi)沒有返回消費結(jié)果,那服務(wù)端就認為遇到了特殊情況,客戶端將“永遠”不會再返回結(jié)果了。在這種場景下,服務(wù)端會主動清理占用,保證消費的繼續(xù)進行。占用超時在JMQ的管理端叫“應(yīng)答超時”,默認值是120秒,也正好匹配了此現(xiàn)象產(chǎn)生的原因。

解決方案

?措施一:超時應(yīng)答超時時間

?調(diào)整應(yīng)答超時,將應(yīng)答超時時間調(diào)小,減少上述場景帶來的影響。

?具體調(diào)整到多少:最近一段時間的消費tp999值的10倍。

?如果最近一周的最大tp999是5秒,那就調(diào)整成50秒.

?措施二:升級支持優(yōu)雅關(guān)機:MQ SDK底層增加支持,應(yīng)對此類場景支持優(yōu)雅關(guān)機,可主動釋放MQ服務(wù)端的鎖。

5.2 JMQ消息過大故障

目前消息發(fā)送,如果在消息體超過一定的大小的情況下,默認會開啟壓縮,但是在一些極限的情況下,仍然會出現(xiàn)消息體過大發(fā)送失敗的情況。對于這一點,筆者還是建議各個系統(tǒng)的業(yè)務(wù)模型需要盡量精簡,盡量降低無關(guān)的業(yè)務(wù)內(nèi)容全部一股腦塞到消息隊列中。

5.3 JMQ存儲故障

某次發(fā)現(xiàn)消息突然出現(xiàn)服務(wù)性能飆高的情況,多輪排查后發(fā)現(xiàn)是MQ服務(wù)器對應(yīng)的1G的下行網(wǎng)絡(luò)帶寬被寫滿,進而導(dǎo)致上行網(wǎng)絡(luò)帶寬發(fā)送也存在問題發(fā)送失敗。

出現(xiàn)這個問題,需得滿足幾個前提條件,首先是消息體比較大,其次是消費方比較多。在流量壓力突增的情況下,所有的消費者都從MQ服務(wù)上去獲取下載消息,類似一堆人去一個集中的服務(wù)器去拷片,理論上無上限瓶頸的網(wǎng)卡直接被打滿。

責任編輯:武曉燕 來源: 京東云開發(fā)者
相關(guān)推薦

2023-03-03 14:07:06

2021-06-28 10:34:55

Linux編程命令行

2020-08-20 10:10:43

Prometheus架構(gòu)監(jiān)控

2017-12-29 08:54:58

高可用數(shù)據(jù)庫架構(gòu)

2022-05-17 11:06:44

數(shù)據(jù)庫MySQL系統(tǒng)

2015-06-02 04:17:44

架構(gòu)設(shè)計審架構(gòu)設(shè)計說明書

2022-08-03 11:54:11

機器學(xué)習(xí)框架開源玩具

2015-06-02 04:34:05

架構(gòu)設(shè)計

2009-12-02 16:33:09

家用路由器安裝說明

2025-09-26 08:52:57

2021-01-15 13:28:53

RNNPyTorch神經(jīng)網(wǎng)絡(luò)

2009-10-12 10:33:05

智能家居布線材料

2009-12-02 16:01:00

2009-12-30 11:12:13

VPN配置說明書

2022-03-15 15:26:16

iPhoneProMotion刷新率

2009-12-30 10:56:50

VPN配置說明書

2025-07-11 01:44:00

架構(gòu)軟件開發(fā)

2009-12-04 10:57:49

無線路由器說明書

2009-10-27 09:02:49

Windows 7說明書下載

2018-04-13 10:49:56

Google Linux 系操作系統(tǒng)
點贊
收藏

51CTO技術(shù)棧公眾號

久久99精品久久久久久久青青日本| 亚洲欧美国产精品专区久久| 国产一级做a爰片久久毛片男| 亚洲爱爱综合网| 在线亚洲国产精品网站| 亚洲香蕉成视频在线观看| 中文字幕66页| 成入视频在线观看| 日本一区免费视频| 51国产成人精品午夜福中文下载| 国产精品成人av久久| 久久综合欧美| 日韩视频永久免费| 可以免费观看av毛片| av免费看在线| 国产亚洲女人久久久久毛片| 亚洲综合在线中文字幕| 天码人妻一区二区三区在线看| 亚洲不卡av不卡一区二区| 亚洲美女av电影| 99国产精品免费视频| 欧美日韩尤物久久| 亚洲午夜久久久久中文字幕久| 亚洲精品一卡二卡三卡四卡| 色偷偷在线观看| 国产精品一区二区在线观看网站| 国产成人久久久| 日本三级欧美三级| 牛牛国产精品| 最近2019好看的中文字幕免费| jizz日本免费| 福利片一区二区| 日韩午夜电影av| 国产成人美女视频| 欧美中文字幕精在线不卡| 亚洲国产欧美一区二区三区丁香婷 | 日本aⅴ在线观看| 欧美午夜精品一区二区三区电影| 亚洲激情自拍图| 亚洲色图欧美另类| 日韩有吗在线观看| 91精品蜜臀在线一区尤物| 国产高潮免费视频| 精品国产欧美日韩一区二区三区| 欧美性猛交xxx| 国产亚洲欧美在线视频| 高清在线视频不卡| 成人免费无遮挡| 99精品欧美一区二区蜜桃免费| 91手机视频在线观看| 中日精品一色哟哟| 久久人人超碰| 国产成人97精品免费看片| 国产区在线观看视频| 亚洲高清资源| 97精品国产97久久久久久春色| 精品亚洲永久免费| 国产一区亚洲| 欧美激情欧美狂野欧美精品| 免费一级片视频| 国内视频精品| 992tv成人免费视频| 久久久久久久久久免费视频| 亚洲一区二区三区高清| 国产91精品青草社区| 天天操天天操天天操天天| 午夜在线播放视频欧美| 国产精品1区2区在线观看| 最好看的日本字幕mv视频大全| 奇米在线7777在线精品 | 手机看片日韩国产| av毛片在线免费| 亚洲成人午夜影院| 日韩av资源在线| 外国电影一区二区| 91精品国产综合久久蜜臀| 国产精品一级无码| 日韩欧美影院| 在线视频日韩精品| 少妇aaaaa| 国产精品婷婷| 国产精品青青在线观看爽香蕉| 一本色道久久综合亚洲| 91成人精品观看| 国产福利资源一区| 欧美一卡二卡在线| 中文字幕精品视频在线| 美女久久99| 精品国产视频在线| 激情五月色婷婷| 免费高清在线视频一区·| 91九色露脸| 可以直接在线观看的av| 亚洲欧洲成人精品av97| 99热久久这里只有精品| 日韩精品影片| 日韩欧美国产不卡| 无码人妻aⅴ一区二区三区69岛| 欧美激情黄色片| 午夜精品久久久久久久久久久久久| 久久久精品毛片| 国产精品系列在线观看| 国产精品一区二区免费| 在线中文资源天堂| 天天综合日日夜夜精品| 欧美精品久久久久久久久25p| 成人搞黄视频| 久久精品久久久久久国产 免费| 日韩久久精品视频| 久久国产精品99久久久久久老狼 | 日韩手机在线观看视频| 无码人妻精品一区二区三区夜夜嗨| 手机看片一区二区| 日本一区二区三区久久久久久久久不 | 免费观看成年在线视频网站| 亚洲激情男女视频| 91人人澡人人爽人人精品| 国产精品网址| 久久久精品国产| 啪啪小视频网站| 91丨九色丨黑人外教| 欧美三级午夜理伦三级老人| 成人精品三级| 国产偷亚洲偷欧美偷精品| 18岁成人毛片| 久久99热99| 色99中文字幕| 密臀av在线播放| 精品久久人人做人人爽| 午夜国产福利一区二区| 久久综合综合久久综合| 欧美日韩国产三区| 国内精彩免费自拍视频在线观看网址| 日韩视频一区二区三区| 欧美激情精品久久久久久免费| 丝袜国产日韩另类美女| 久久久久久a亚洲欧洲aⅴ| 国产丝袜精品丝袜| 欧美成人精品高清在线播放| 国产97免费视频| 国产主播一区二区| 一个色的综合| 四虎地址8848精品| www.午夜精品| 91精品国产综合久| 成人欧美一区二区三区| 中文字幕亚洲影院| 午夜日韩在线| av色综合网| 白白色在线观看| 亚洲精品一区在线观看| 国产一级av毛片| www.日韩大片| 欧美韩国日本在线| 欧美女王vk| 国产精品高潮呻吟久久av无限| 搞黄视频免费在线观看| 欧美色电影在线| 尤物在线免费视频| 国产福利一区在线观看| 丰满的少妇愉情hd高清果冻传媒 | 一区二区三区在线观看www| 成人久久网站| 久久国产一区二区三区| jlzzjlzzjlzz亚洲人| 亚洲一区二区三区中文字幕| 日本国产在线视频| 久久国产直播| 亚洲视频sss| 视频免费一区二区| 91大神在线播放精品| 欧美日韩在线精品一区二区三区激情综| 色狠狠桃花综合| 99国产精品免费| 国产麻豆欧美日韩一区| 青青青青草视频| 精品国产一区二区三区| 国产自产女人91一区在线观看| 综合图区亚洲| 日韩精品视频在线观看网址| 波多野结衣理论片| 亚洲人精品午夜| 在线免费播放av| 麻豆一区二区三| 免费一级淫片aaa片毛片a级| 久久99久久人婷婷精品综合| 91精品在线国产| 韩日毛片在线观看| 久久精品视频一| 色久视频在线播放| 91麻豆精品国产91久久久久久| 日本学生初尝黑人巨免费视频| 久久久久久一级片| 在线观看视频在线观看| 亚洲自啪免费| 99中文字幕在线观看| 九九热线有精品视频99| 99影视tv| 欧洲成人一区| 欧美一区二区三区免费视| 欧美极品另类| 亚洲精品综合久久中文字幕| 国产成人久久精品77777综合 | 亚洲男人的天堂在线观看| 免费a在线观看播放| 国模无码大尺度一区二区三区| 国产97在线 | 亚洲| 亚洲精品va| 色综合视频二区偷拍在线| av在线亚洲色图| 92看片淫黄大片欧美看国产片 | 狠狠色丁香久久综合频道| 亚洲精品在线免费| 婷婷精品视频| 国产精品免费在线播放| 天堂久久一区| 国产精品久久久久久久av大片| av免费不卡| 欧美情侣性视频| 免费av网站在线看| 在线午夜精品自拍| 每日更新av在线播放| 亚洲福利视频网| www香蕉视频| 欧美剧情片在线观看| www.av88| 在线观看国产精品网站| 黄色免费av网站| 午夜欧美在线一二页| 久久国产精品二区| 亚洲精品视频自拍| 国产va在线播放| 亚洲色图欧洲色图| 男人的午夜天堂| 中文字幕五月欧美| 最新av电影网站| 国产精品久久一卡二卡| 精品丰满少妇一区二区三区| 久久久久久久综合色一本| 3d动漫精品啪啪一区二区下载| bt7086福利一区国产| 特级西西人体4444xxxx| 成人精品gif动图一区| 国产免费无码一区二区| 国产99久久久国产精品| 一卡二卡三卡四卡五卡| 国产精品亚洲一区二区三区在线| 亚洲色图欧美自拍| 国产精品综合在线视频| 91人妻一区二区三区| 国产成人亚洲综合a∨婷婷| 久久久久无码国产精品一区李宗瑞| 国产精品亚洲成人| 久久久久久久久久久久国产精品| 国产精品888| 国产综合内射日韩久| 99久久国产综合色|国产精品| 日本黄色免费观看| 久久蜜桃av一区精品变态类天堂| 亚洲激情视频小说| 国产精品欧美一级免费| 日韩一区二区不卡视频| 亚洲一区二区三区在线| 人人干人人干人人干| 色婷婷综合久色| 在线观看亚洲一区二区| 欧美一区二区三区免费观看视频| 亚洲黄色一级大片| 日韩av在线最新| 91高清在线| 欧美日韩国产va另类| 日本不良网站在线观看| 国产精品免费电影| 精品久久久久久久久久岛国gif| 99在线观看视频| 一本色道久久综合亚洲精品酒店 | 久久午夜激情| 国产精品嫩草影视| 91啪亚洲精品| 国产精品久久久免费看| 亚洲一区二区欧美日韩| 中文字幕精品三级久久久| 欧美喷潮久久久xxxxx| 成人激情四射网| 夜夜嗨av一区二区三区免费区| 麻豆视频在线| 欧美一级大胆视频| 自拍偷拍欧美日韩| 久久伦理网站| 自由日本语亚洲人高潮| av观看免费在线| 国产经典欧美精品| 四虎永久免费在线观看| 亚洲精品久久久久久国产精华液| 久久黄色精品视频| 日韩一区二区电影| 国产综合在线观看| 久久99久久99精品免观看粉嫩| 欧美极品免费| 国产另类第一区| 91精品啪在线观看国产81旧版| 欧美 国产 日本| 国产成a人亚洲精| 精品日韩在线视频| 精品免费在线视频| 99久久久久成人国产免费| 亚洲区免费影片| 97蜜桃久久| 亚洲尤物视频网| 欧美3p视频| 日韩精品一区二区三区色欲av| 岛国一区二区三区| 影音先锋男人资源在线观看| 日韩欧美中文字幕在线播放| www香蕉视频| 欧美成人免费全部| 免费视频成人| 日韩三级电影网站| 国产日产高清欧美一区二区三区| 色哟哟免费视频| 中文字幕在线免费不卡| 中文字幕一区二区人妻视频| 亚洲国产成人精品久久久国产成人一区 | 丁香桃色午夜亚洲一区二区三区| www.黄色com| 欧洲另类一二三四区| 天天干天天色天天| 久久久久久久久久亚洲| 亚洲综合影院| 国产香蕉一区二区三区| 精品一区二区三区视频在线观看| 美女100%无挡| 日韩欧美亚洲一二三区| 五月婷婷开心中文字幕| 久久免费视频观看| 91蜜桃臀久久一区二区| 在线观看亚洲视频啊啊啊啊| 日本不卡一区二区三区高清视频| 国产美女精品久久| 欧美性极品xxxx做受| 免费福利在线视频| 国产aaa精品| 国产精品自拍区| 色一情一乱一伦一区二区三区日本| 91香蕉视频mp4| 久久久久久91亚洲精品中文字幕| 日韩经典一区二区三区| 亚洲精品动漫| 亚洲看片网站| 精品中文字幕一区二区| 91麻豆免费视频网站| 日韩欧美久久久| 欧美1—12sexvideos| 国产精品视频免费一区| 一区二区91| 91资源在线播放| 欧美乱妇20p| 综合图区亚洲| 久久99精品久久久久久久青青日本 | 日本免费一区二区三区视频观看| 蜜桃精品噜噜噜成人av| 妞干网在线免费视频| 亚洲国产成人自拍| 一级黄色免费片| 欧美日本在线视频中文字字幕| 超碰一区二区三区| 日批视频在线免费看| 国产欧美久久久精品影院| 国产精品乱码久久久| 欧美日韩高清区| 亚洲老女人视频免费| 91极品视频在线观看| 悠悠色在线精品| 水莓100国产免费av在线播放| 日韩av日韩在线观看| 五月婷婷亚洲| 这里只有精品在线观看视频 | 亚洲欧洲成人自拍| 可以免费看毛片的网站| 日本人成精品视频在线| 水蜜桃久久夜色精品一区| 日韩少妇一区二区| 欧美亚洲国产bt| 黑人精品视频| 日本一区二区三区精品视频| 国产麻豆精品视频| 亚洲婷婷综合网| 久久不射电影网| 亚洲国产合集| 国产乱叫456| 狠狠操狠狠色综合网| 久草中文在线| 欧美一区二区三区四区夜夜大片 | 激情综合在线| 无码人中文字幕| 亚洲精品99999| 四虎影视国产精品| 国产黄色特级片| 亚洲愉拍自拍另类高清精品| 粉嫩av一区|