分佈式場景中。若服務不穩定,會致使調用方服務也不可用,從而形成雪崩效應。所以要對在原服務不可用時進行熔斷降級處理。java
熔斷降級能夠服務端限流、網關限流、客戶端限流。spring
1. 客戶端限流:在調用方法發起請求時檢查是否達到閥值。若達到閥值,不發起調用請求api
優勢:能夠在服務消費端直接控制流量出口,減小沒必要要請求的發起。bash
缺點:客戶端須要感知服務運行指標和容災規則。每一個業務方須要重複開發網絡
2. 服務端限流:服務提供方自定義容災邏輯,在收到請求後再根據當前狀態判斷是否走fallback邏輯併發
優勢:容災規則、閥值徹底封裝在服務提供者。對調用方無感知。app
缺點:若服務提供者都掛了,沒法進行容災。框架
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:降級方法,必須指定
/**
* 保護的方法
* @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方式。容災規則、運行指標也沒有持久化存儲。後期若是須要,能夠藉助現有的開源控制檯進行二次開發。