剔除重复_微服务发生故障后,我是如何做到自动剔除异常的Server?
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)行原理如上圖所示,大致可以分為以下幾步:
服務(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ù)不同場景做不同的適配。目前斷路器的工作算法大致如下
當(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 做出記錄。
服務(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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lora发射和接收原理_四个要点,帮你搞
- 下一篇: 技术方案包括哪些内容_揭秘:网络营销推广