精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

夜夜嗨av一区二区三区四区 | 黄色动漫在线观看| 美女一区二区久久| 久久精品视频在线播放| 韩国av中国字幕| 亚洲欧美韩国| 亚洲人成小说网站色在线 | 亚洲一区av在线| 清纯唯美一区二区三区| 99er热精品视频| 久久国产精品毛片| 久热精品视频在线观看| 国产精品无码专区| 国产又粗又猛又爽又黄的视频四季 | 免费在线观看亚洲视频| 97最新国自产拍视频在线完整在线看| 国产一区二区三区精品视频| 2019亚洲男人天堂| 一级片一级片一级片| 日韩三级毛片| 日韩一区二区在线观看视频| 日韩av播放器| caoporn视频在线| 国产精品视频一二三区| 久久精品五月婷婷| www.色视频| 日本视频一区二区| 97人洗澡人人免费公开视频碰碰碰| 国产喷水在线观看| 深爱激情久久| 亚洲精品国产福利| 亚洲AV无码久久精品国产一区| 性欧美1819sex性高清| 一区二区三区四区五区视频在线观看| 日韩精品久久久免费观看| 亚洲精品.www| 国产在线视频不卡二| 日韩免费在线视频| 欧美三日本三级少妇99| 亚洲高清不卡| 欧美激情视频在线免费观看 欧美视频免费一 | 国产人妖乱国产精品人妖| 国产精品久久波多野结衣| 一级黄色录像大片| 蜜臀av性久久久久av蜜臀妖精| 欧美一级大片在线免费观看| 日本在线视频免费观看| 亚洲视频免费| 欧美极品少妇全裸体| 日韩欧美综合视频| 亚洲欧美在线专区| 日韩中文字幕视频在线| 男女全黄做爰文章| 成人在线电影在线观看视频| 亚洲天堂久久av| 欧美黄色一级生活片| 色橹橹欧美在线观看视频高清| 欧美α欧美αv大片| 乳色吐息在线观看| 91精品导航| 亚洲第一页在线| 亚洲永久无码7777kkk| 日韩精选在线| 日韩美女av在线| 久久精品一区二区免费播放| 国产精品密蕾丝视频下载| 国产视频精品va久久久久久| 伊人网在线视频观看| 精品久久久久久久久久久aⅴ| 伊人成人开心激情综合网| 欧美福利在线视频| 久久精品亚洲人成影院 | 亚洲国产精品久久久| 99精品一区二区三区无码吞精| 老司机aⅴ在线精品导航| 日韩电影中文字幕一区| 丰满少妇一区二区| 久久一区91| 欧美老女人性生活| 日韩精品一区二区不卡| 久久久久国产精品一区三寸| 国产精品一区二区电影| 国内毛片毛片毛片毛片| 成人一区二区三区中文字幕| 欧美成人第一区| 永久免费av片在线观看全网站| 亚洲男人的天堂在线观看| 成人午夜视频在线观看免费| 日韩电影免费观| 欧美精品v国产精品v日韩精品 | 波多野结衣乳巨码无在线| 日本免费一区二区三区四区| 7777精品伊人久久久大香线蕉经典版下载 | 午夜一级黄色片| 韩国欧美一区二区| 激情伦成人综合小说| 91sp网站在线观看入口| 亚洲成人动漫一区| 性生活免费在线观看| 国产精品对白| 日韩中文字幕在线视频| 亚洲综合一二三| 久久国内精品自在自线400部| 国产欧美日韩伦理| 日本韩国在线视频爽| 亚洲精品一卡二卡| 杨幂毛片午夜性生毛片| 国产精品欧美大片| xxxxxxxxx欧美| 69成人免费视频| 国产激情一区二区三区四区| 欧美黑人3p| 性欧美videoshd高清| 欧美亚洲一区三区| 久久久久国产精品区片区无码| 99九九热只有国产精品| 亲子乱一区二区三区电影 | 国产成人免费高清视频| 久久亚洲精品爱爱| 亚洲激情视频在线播放| 日韩国产第一页| 日韩电影在线看| 国产在线精品一区二区中文 | 久久国产精品亚洲人一区二区三区| 久久久久久av| 国产高清第一页| 中文字幕中文乱码欧美一区二区| 日韩视频免费在线播放| 丝袜连裤袜欧美激情日韩| 欧美精品手机在线| 国产精品伦一区二区三区| 国产日韩精品一区二区三区在线| 免费看国产曰批40分钟| 亚洲综合影院| 欧美大片在线免费观看| 国产欧美日韩综合精品一区二区三区| 中文字幕电影一区| 午夜欧美福利视频| 精品国产网站| 国产精品爱啪在线线免费观看| 亚洲色欧美另类| 亚洲国产精品一区二区久久恐怖片| 91丨porny丨九色| 在线精品视频在线观看高清| 91九色单男在线观看| 日本成人网址| 欧美日韩的一区二区| 麻豆精品国产免费| 久久av资源站| 亚洲资源视频| 激情综合五月| 欧美丰满少妇xxxxx| 国产suv一区二区| 亚洲黄色片在线观看| 欧美日韩理论片| 欧美韩日精品| 不卡一卡2卡3卡4卡精品在| 日本三级在线观看网站| 亚洲精品在线三区| 人妻丰满熟妇av无码区| 国产亚洲一区二区三区在线观看| 99视频在线免费| 成人精品电影| 91在线高清视频| av电影院在线看| 亚洲乱码国产乱码精品精| 日本中文字幕在线观看视频| 国产精品美女久久久久aⅴ | 精品淫伦v久久水蜜桃| 欧美性受xxxx白人性爽| 国产三级在线| 91精品国产一区二区三区香蕉| 国产一级生活片| 26uuu精品一区二区 | 成人深夜在线观看| www.中文字幕在线| 青青草91久久久久久久久| 91欧美精品午夜性色福利在线| 黄网在线免费看| 亚洲欧美日韩天堂| 国产精品九九九九| 午夜欧美在线一二页| 亚洲理论片在线观看| 国模大尺度一区二区三区| 色欲色香天天天综合网www| 精品视频久久| 成人精品水蜜桃| 欧洲av一区二区| 欧美精品日韩三级| 国产综合在线观看| 欧美成人综合网站| 成人免费视频国产免费| 亚洲精品网站在线观看| 国产精品1000部啪视频| 国产一区在线视频| 一本大道熟女人妻中文字幕在线| 婷婷成人基地| 欧美午夜精品理论片a级大开眼界| av在线精品| 国产91在线高潮白浆在线观看| 国产在线激情视频| 亚洲欧美日韩成人| 午夜精品久久久久久久第一页按摩 | 欧美一区=区三区| 亚州成人av在线| 米奇精品一区二区三区| 亚洲欧美日韩中文视频| 国产成年妇视频| 欧美日韩亚洲高清一区二区| 伊人国产在线观看| 专区另类欧美日韩| 中文字幕成人动漫| 97se亚洲国产综合自在线| 992tv人人草| 久久国产精品99久久人人澡| 国产精品宾馆在线精品酒店| 欧美jizzhd精品欧美巨大免费| 日韩欧美第二区在线观看| 欧美a级网站| 国产精品久久久久av福利动漫| 日韩成人一区| 国产精品久久电影观看| 三妻四妾完整版在线观看电视剧| 欧美大码xxxx| av网站在线免费看推荐| 色综久久综合桃花网| 天堂在线中文网| 精品成人一区二区| 国产suv精品一区二区69| 欧美卡1卡2卡| 国产精品久久久久精| 欧美日韩一区二区不卡| 日韩国产亚洲欧美| 欧洲av在线精品| 蜜臀精品一区二区三区| 色综合天天综合在线视频| 91看片在线播放| 五月开心婷婷久久| 91香蕉在线视频| 五月天激情小说综合| 日韩美女黄色片| 欧美午夜影院在线视频| 国产微拍精品一区| 色域天天综合网| jizz国产在线观看| 欧美视频完全免费看| 国产亚洲欧美日韩高清| 日本久久电影网| 日本妇乱大交xxxxx| 欧美三级电影一区| 一本一道人人妻人人妻αv| 欧美三级资源在线| 97人妻精品一区二区三区软件| 欧美日本免费一区二区三区| 一区二区三区免费在线视频| 91精品国产综合久久国产大片| av资源免费看| 亚洲高清av在线| 色视频精品视频在线观看| 亚洲老头老太hd| 网友自拍视频在线| 欧美刺激性大交免费视频| 动漫一区二区| 欧美制服第一页| 国产69精品久久| 亚洲va国产va天堂va久久| 亚洲开心激情| 美脚丝袜一区二区三区在线观看| 国产aⅴ精品一区二区三区久久| 亚洲欧美日韩国产yyy| 亚洲第一偷拍| 久久国产精品视频在线观看| 久久精品观看| 亚洲精品第三页| www.日韩精品| 无码人妻aⅴ一区二区三区69岛| 国产欧美中文在线| 青草影院在线观看| 狠狠干狠狠久久| 亚洲天堂视频在线| 欧美成人video| 国产在线一在线二| 美女精品视频一区| gay欧美网站| 亚洲自拍av在线| 在线视频亚洲专区| 丰满女人性猛交| 性伦欧美刺激片在线观看| 免费看国产黄色片| 成人午夜电影久久影院| 国产黄色大片免费看| 夜夜嗨av一区二区三区网页| 久久影视中文字幕| 日韩欧美国产1| 成年人在线观看| 97激碰免费视频| 高清在线一区二区| 欧美日韩电影一区二区| 欧美精品不卡| 天天干天天综合| 97久久超碰精品国产| avove在线播放| 欧美在线观看视频一区二区| 秋霞av鲁丝片一区二区| 日韩三级成人av网| 欧美gay视频| 国产女人水真多18毛片18精品| 色呦哟—国产精品| av免费网站观看| 99视频精品全部免费在线| 精品一区在线观看视频| 欧洲国产伦久久久久久久| 日韩资源在线| 欧美国产日韩二区| 99久久99九九99九九九| 日本精品一区| 亚洲精品1234| 日本少妇xxxx软件| 亚洲人一二三区| 国产精品女同一区二区| 伊人亚洲福利一区二区三区| 亚洲欧美电影| 久久五月天婷婷| 一区二区三区成人精品| 午夜福利三级理论电影| 亚洲精品国产视频| 国产精品特级毛片一区二区三区| 在线精品高清中文字幕| 中文字幕日本一区二区| 欧美日韩一区在线观看视频| 亚洲理论在线| 久久久午夜精品福利内容| 亚洲国产中文字幕| 亚洲第一页视频| 欧美疯狂性受xxxxx另类| 国产精品美女久久久久| 曰韩不卡视频| 激情偷乱视频一区二区三区| avhd101老司机| 欧美性猛片aaaaaaa做受| 国产鲁鲁视频在线观看免费| 国产999视频| 精品国产一区二区三区av片| 国产极品美女高潮无套久久久| 久久综合国产精品| 国产精品乱码一区二区视频| 一区二区福利视频| 日本午夜精品久久久久| 欧美日韩视频免费在线观看| 九色综合狠狠综合久久| 日韩va亚洲va欧美va清高| 91精品国产色综合久久不卡蜜臀 | 亚洲免费视频成人| а√中文在线资源库| 欧美黑人国产人伦爽爽爽| 亚洲国产精品免费视频| 999一区二区三区| 99riav久久精品riav| 日日夜夜操视频| 日韩中文在线观看| 日韩精品一区二区三区中文 | 亚洲韩国欧洲国产日产av| 捆绑调教日本一区二区三区| 免费精品视频一区二区三区| 丝袜诱惑制服诱惑色一区在线观看| 女人黄色一级片| 91精品国产综合久久福利| 久久电影网站| 欧美一区二区三区四区夜夜大片| 琪琪一区二区三区| 强行糟蹋人妻hd中文| 亚洲国产精品va在线看黑人| av高清一区| ijzzijzzij亚洲大全| 北条麻妃国产九九精品视频| 特级西西444www大精品视频免费看| 国产一区二区三区在线播放免费观看| 欧美风情在线视频| 成人在线免费观看视频网站| 91麻豆精品在线观看| 亚洲图片视频小说| 欧美精品18videos性欧| 国产乱码精品一区二区三区四区| 亚洲精品第三页| 欧美性videos高清精品| 91网在线播放| 国产精品国产三级国产专区53 | 亚洲电影影音先锋| 狠狠人妻久久久久久综合蜜桃| 欧美日韩一级视频| zzzwww在线看片免费| 一区二区三区四区五区精品| 丁香一区二区三区| 一区二区视频在线免费观看| 欧美激情三级免费| 色综合天天爱| 欧美图片一区二区| 69av一区二区三区| 日韩在线免费| 国产h视频在线播放|