日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

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

工作流程

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

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

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

    參數定義

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

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

    斷路器工作原理

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

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

    框架中算法實現如下:

    ????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;
    ????}

    記錄服務狀態

    當 loadBalancerCommand 對服務請求做出處理之后,根據返回的狀態對 serverStats 做出記錄。

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

    AvailabilityFilteringRule 通過一定的規則選擇合適的 server 實例。首先它用 roundRobinRule 加權輪詢算法選取一個 sevrer 實例。接著對選出的 server 實例應用上述的斷路算法判斷是否應該斷路,如果是斷路狀態,那么將會重新通過 roundRobinRule 去選擇 server 實例,這里最多重試 10 次。如果經過了 10 次,還沒有選出合適的實例,意味著也許所有實例都被熔斷了。那么死活還是得挑一個的,這里會通過父類 Rule 去選擇實例,而父類 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

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。