分佈式熔斷降級平臺aegis

NO IMAGE

現狀

分佈式場景中。若服務不穩定,會導致調用方服務也不可用,從而造成雪崩效應。因此要對在原服務不可用時進行熔斷降級處理。

分析

熔斷降級可以服務端限流、網關限流、客戶端限流。

1. 客戶端限流:在調用方法發起請求時檢查是否達到閥值。若達到閥值,不發起調用請求

優點:可以在服務消費端直接控制流量出口,減少不必要請求的發起。

缺點:客戶端需要感知服務運行指標和容災規則。每個業務方需要重複開發

2. 服務端限流:服務提供方自定義容災邏輯,在收到請求後再根據當前狀態判斷是否走fallback邏輯

優點:容災規則、閥值完全封裝在服務提供者。對調用方無感知。

缺點:若服務提供者都掛了,無法進行容災。

3. 網關限流:原本直接調用提供者的請求都由網關層代理轉發。容災規則的配置、降級邏輯都封裝在網關層。

優點:客戶端、服務端都無需感知容災邏輯。

缺點:多了一次網絡請求、rt變大

大部分情況下,我們都是選擇服務端限流。但客戶端對數據平臺的接口是強依賴的。若搜索應用掛了,客戶端還是需要看到數據。相比高可用,略微的rt變大是可以接受的,所以啟動一個數據容災網關

技術選型

現在瞭解到的開源容災框架有hystrix、sentinel兩種。

hystrix:常用於springcloud的一個熔斷降級組件。主要功能是不同服務之間的資源隔離、失敗降級。底層實現是Rxjava。它提供兩種資源隔離的模式:信號量隔離和線程池隔離。一般使用線程池隔離。耗費一定資源,但相比之下支持超時和異步執行。聽起來可以覆蓋大部分場景,但它不支持更高要求的流控,如qps的控制。所以需要單獨採用令牌漏桶來做流量控制。

sentinel:阿里開源的分佈式流量控制組件。支持流控、熔斷降級、系統保護等。所有的資源都對應一個資源名稱以及一個Entry。每一個Entry創建的時候,同時也會創建一系列插件(系統保護插件:SystemSlot、流控插件:FlowSlot、熔斷降級插件LDegradeSlot等)。每個插件會監控自己職責範圍內的指標。NodeSelectorSlot將各個資源的調用路徑以樹狀存儲,用於限流降級。調用者通過創建上下文、請求token來執行方法。若沒有拋出BlockException,表示請求成功。它支持併發數/qps的流量控制、也支持熔斷降級。

對比:1.hystrix的熔斷都圍繞線程池展開。更適合做資源隔離,但單個應用有多個服務時線程池開銷會造成浪費。hystrix是單個超時立即熔斷,控制力度更細。多個微服務的場景可以考慮用這種。2.sentinel是基於併發數,支持的場景也更復雜,開銷小,適合在保證服務穩定的情況下提高吞吐量。但它的超時是5次請求的平均響應時間。並不是很嚴格。但對於大多數場景而言可以接受

接入方式

sentinel支持api和註解兩種接入方式。作為容災網關,之後可以會接很多接口。為了接入簡單、對代碼無侵入。需要使用註解的方式。但是原生的@SentinelResource有幾個問題:

1. 只能指定資源名稱、fallback方法。用戶還是需要通過api創建容災規則,

2. 而且fallback方法入參要加上BlockException。這樣的接入方式不是很優雅。

3. 流控異常FlowException的方法要另外指定。

於是基於sentinel封裝了一層自定義註解@AegisResource

@AegisResource(value = “hello”,limitThread = 0,timeOut = 100,failRate = 0.5,timeWindows = 100,fallback = “exceptionHandler”)

參數說明:

value:資源名稱,默認為方法名

limitThread:最大線程數,默認-1,即不啟用

timeOut:接口超時時間,默認-1,即不啟用

failRate:失敗率,默認-1,即不啟用

timeWindows:觸發降級但持續時間,默認100

fallback:降級方法,必須指定

接入demo


/**
* 保護的方法
* @return
*/
@GetMapping("resourcetest")
@AegisResource(value = "hello",limitThread = 0,timeOut = 100,failRate = 0.5,timeWindows = 100,fallback = "exceptionHandler")
public String hello() {
return "ok";
}
/**
* 降級的方法
* @return
*/
public String exceptionHandler() {
// Do some log here.
return "Oops, error occurred at " ;
}

新接口只需寫好希望執行的方法和降級方法,然後在希望執行的方法上加入@AegisResource(fallBack=“fallback的方法名”)就可以無侵式入地進行容災。切面定義了默認容災閥值。也可以在對應屬性上設置自定義的閥值。

後期規劃

目前容災網關可以滿足目前的需求。目前有開源的控制檯,可以查看服務調用大盤,動態調整容災規則。缺點是目前指標的蒐集是http方式。容災規則、運行指標也沒有持久化存儲。後期如果需要,可以藉助現有的開源控制檯進行二次開發。

相關文章

詳解CountDownLatch

線程池

第一次來到

ES寫入性能優化