日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

剔除重复_微服务发生故障后,我是如何做到自动剔除异常的Server?

發(fā)布時間:2025/4/5 77 豆豆
生活随笔 收集整理的這篇文章主要介紹了 剔除重复_微服务发生故障后,我是如何做到自动剔除异常的Server? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Ribbon 是 Netflix 出品的一套負(fù)載均衡組件,提供了許多 Rule 規(guī)則從負(fù)載列表中選取合適的 server 實(shí)例。當(dāng)實(shí)例出現(xiàn)問題時候,需要將這部分異常的服務(wù)提供者從負(fù)載列表中剔除,從而避免雪崩效應(yīng)。而 Riibbon 本身具有自動移除問題實(shí)例的功能,于是我們可以結(jié)合 Ribbon 對現(xiàn)有的負(fù)載均衡策略做一些改進(jìn),實(shí)現(xiàn)自動故障剔除功能。

工作流程

Ribbon 中實(shí)現(xiàn)自動移除問題實(shí)例的 Rule 是 AvailabilityFilteringRule,它的運(yùn)行原理如上圖所示,大致可以分為以下幾步:

  • 在 LoadbalancerCommand 發(fā)起 choose server 請求時候,首先會通過 RoundRobinRule 去服務(wù)器列表 serverList 獲取 server,此處 RoundRobinRule 是修改過的帶權(quán)重的加權(quán)輪詢算法器。
  • 從 RoundRobinRule 獲取一個 server 之后,會 AvailabilityPredicate 這個斷言器去判斷是否是問題實(shí)例。簡單來說,就是從 LoadBalancerStats 中獲取這個 server 的狀態(tài) serverStats,然后在 serverStats 這個狀態(tài)機(jī)中去判斷是否應(yīng)該斷路。
  • 經(jīng)過 serverStats 的斷路判斷之后,如果是需要斷路的,那么表明是問題實(shí)例,如果不需要,則返回給 LoadBalancerCommand 一個正常的 server 實(shí)例。
  • LoadBalancerCommand 在處理完請求后,無論成功與否都對 serverStats 做一次相應(yīng)的狀態(tài)記錄。
  • 服務(wù)狀態(tài) ServerStats

    結(jié)合實(shí)際業(yè)務(wù)需求,在 serverStats 中,目前定義了兩類異常,連接異常 (主要指 tcp 層面的,包括 sokcetException,socketTimeoutException,ConnectException) 以及不可用異常(主要是底層通信框架 rxNetty 拋出的異常,包括 timeoutException 以及 PoolExhaustedException)。

    參數(shù)定義

    考慮到兩種異常的發(fā)生場景的差異,為這兩類異常分別設(shè)置了各自的連續(xù)失敗閾值 (connectionFailureThreshold,unavailableThreshold) 以及斷路超時時間(connectionFailureCircuitTimeout,unavailableCircuitTimeout)。其中不可用異常參數(shù) (unavailableThreshold,unavailableCircuitTimeout) 會暴露給使用者,使用 springboot 的項(xiàng)目可以直接讀取 yml 文件或者托管到第三方配置中心。

    而其中連接失敗異常相關(guān)的參數(shù),考慮到較為底層,使用者不大關(guān)心,是默認(rèn)設(shè)置好了,只通過讀取環(huán)境變量的方式來允許改動。

    斷路器工作原理

    從上面定義的參數(shù)就指定,目前斷路器統(tǒng)計失敗是靠連續(xù)失敗次數(shù)去判斷斷路邏輯的。之后可以根據(jù)不同場景做不同的適配。目前斷路器的工作算法大致如下

  • 計算累計連接失敗計數(shù) successiveConnectionFailureCount 是否超過 鏈接失敗閾值 connectionFailureThreshold。如果 successiveConnectionFailureCount < connectionFailureThreshold,即尚未超過限額,則熔斷時間為 0 ;反之,如果超過限額,則進(jìn)行步驟 2 的計算
  • 計算失敗基數(shù),最大不得超過 16。diff = (failureCount - threshold) > 16 ? 16 : (failureCount - threshold)
  • 根據(jù)超時因子 timeoutFactor(目前默認(rèn)寫死為 10) 計算超時時間:blackOutSeconds = (1 << diff) * timeoutFactor;
  • 超時時間不得超過最大超時時間 connectionFailureCircuitTimeout 上線
  • 計算完連接失敗異常相應(yīng)的超時時間 connectionFailureblackOutPeriod 之后,用不可用異常對應(yīng)的參數(shù)去重復(fù)一下 1-4 步驟算出不可用異常對應(yīng)的超時時間 unavailableblackOutPeriod。兩者取最大值作為 blackOutPeriod。
  • 將最后一次失敗時間 lastConnectionFailedTimestamp 加上 blackOutPeriod 超時間隔,作為當(dāng)前斷路器剛關(guān)閉的時間。
  • 每一次請求來,只要比較當(dāng)前時間與步驟 6 算出的時間即可,如果當(dāng)前時間較大,說明過了斷路器剛關(guān)閉的時間,可以正常提供服務(wù),否則表明服務(wù)是斷路狀態(tài)。
  • 當(dāng)有鏈接失敗情況出現(xiàn)斷路邏輯時,將會最多:1<<16 * 10 = 655360 s (如果超過自定義超時時間閾值,則最大為自定義超時時間),最少 1<<0*10 = 10 s 的請求熔斷時間,再此期間內(nèi),此 Server 將會被忽略。熔斷的超時時間在沒有超過自定義超時閾值的情況下,會隨著該 server 的失敗次數(shù)呈指數(shù)級動態(tài)增加。如果當(dāng)自定義閾值很大,而一個服務(wù)實(shí)例連續(xù)失敗很多次,那他基本就沒什么希望被調(diào)用到了。。

    框架中算法實(shí)現(xiàn)如下:

    ????private?long?getCircuitBreakerBlackoutPeriod(AtomicInteger?atomicInteger,?Integer?threshold,?Integer?circuitTimeout)?{
    ????????final?int?failureCount?=?atomicInteger.get();
    ????????if?(failureCount?????????????return?0;
    ????????}
    ????????final?int?diff?=?(failureCount?-?threshold)?>?16???16?:?(failureCount?-?threshold);
    ????????int?blackOutSeconds?=?(1?<????????if?(blackOutSeconds?>?circuitTimeout)?{
    ????????????blackOutSeconds?=?circuitTimeout;
    ????????}
    ????????return?blackOutSeconds?*?1000L;
    ????}

    記錄服務(wù)狀態(tài)

    當(dāng) loadBalancerCommand 對服務(wù)請求做出處理之后,根據(jù)返回的狀態(tài)對 serverStats 做出記錄。

  • 每當(dāng)服務(wù)正常返回時候,會清空兩種異常的熔斷統(tǒng)計。
  • 每當(dāng)服務(wù)異常,但是異常不是定義的兩種異常中的任何一種,也會清空兩種異常的熔斷統(tǒng)計。
  • 每當(dāng)服務(wù)異常,并且異常是兩種異常中的一種,則會增加相應(yīng)異常的熔斷統(tǒng)計,并刷新最后失敗時間 lastConnectionFailedTimestamp 這一參數(shù)。
  • 服務(wù)路由規(guī)則

    AvailabilityFilteringRule 通過一定的規(guī)則選擇合適的 server 實(shí)例。首先它用 roundRobinRule 加權(quán)輪詢算法選取一個 sevrer 實(shí)例。接著對選出的 server 實(shí)例應(yīng)用上述的斷路算法判斷是否應(yīng)該斷路,如果是斷路狀態(tài),那么將會重新通過 roundRobinRule 去選擇 server 實(shí)例,這里最多重試 10 次。如果經(jīng)過了 10 次,還沒有選出合適的實(shí)例,意味著也許所有實(shí)例都被熔斷了。那么死活還是得挑一個的,這里會通過父類 Rule 去選擇實(shí)例,而父類 rule 的斷言器定義的是 always true。

    public?Server?choose(Object?key)?{
    ????????int?count?=?0;
    ????????Server?server?=?roundRobinRule.choose(key);
    ????????while?(count++?<=?10)?{
    ????????????if?(predicate.apply(new?PredicateKey(server)))?{
    ????????????????return?server;
    ????????????}
    ????????????server?=?roundRobinRule.choose(key);
    ????????}
    ????????return?super.choose(key);
    ????}


    作者:fredalxin

    來源鏈接:

    https://fredal.xin/loadbalancer-with-ribbon

    總結(jié)

    以上是生活随笔為你收集整理的剔除重复_微服务发生故障后,我是如何做到自动剔除异常的Server?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。