Spring Cloud斷路器Hystrix原理讀書筆記
以前寫的相關文章:
《Spring Cloud斷路器Hystrix》
《Java設計模式,Spring Cloud的Hystrix中的命令模式》
《Spring Cloud Feign重試》
服務雪崩
假設一個場景,我們去蘋果店買新出的iPhone,店員提供一站式服務:試用、支付、交貨。但是由於大家都知道的原因,交貨一直很慢很慢,客戶、店員不停地去交貨窗口提交請求,最終店裡所有的店員和客戶都堆積到交貨窗口,而外面的客戶不停地湧入店裡,卻沒人服務,整個店都崩潰了——服務雪崩。
應對方法有幾個:
1、 限流,比如排隊,把隊伍搞的曲里拐彎的,想進店要繞好遠的路。也或者店裡人數達到閾值就拉個警戒線不再放人進去。想想每個工作日早高峰,北京幾個重要地鐵站的外面,就是這個場景。
2、 緩存,店裡多備貨,不用去庫房拿貨,太耽誤時間。
3、 擴容,增加店面積,店員。
4、 熔斷,交貨窗口直接關閉,告知店員和客戶,您也別來了,來了也沒用,後續怎麼處理,你們商量著辦就行了(fallBack)。
5、 服務降級,像試用這種相對不重要的環節,就直接PASS掉,節約時間,集中資源辦好後面重要的環節。
Hystrix
終於說到本文主角了。
為了保護系統免於服務雪崩,Hystrix的設計原則有:
隔離、熔斷、命令模式。
隔離
這個很好理解,不再多解釋。Hystrix的隔離機制有兩種:
1、 線程池:給每個服務分配一個線程池,內含10(默認)個線程,當線程池滿了,第11個請求過來的時候,開始排隊,隊伍上限為5(默認),第16個請求過來的時候,直接走fallback流程,不再對服務進行請求。
已經執行請求的線程在調用結束後反饋調用情況,交由Metrics保存,根據Metrics里的計數,計算服務的健康狀態,從而決定是否熔斷。
好處是,當並發高起來的時候,就算線程池滿了,無法執行服務調用,也可以把請求放入隊列等待,不至於立即fallback。
2、 信號量:有一個原子計數器,也即信號量,記錄了現在運行線程的數量。當新請求進來的時候,先判斷信號量是否達到閾值10(默認),如果小於,則+1,繼續執行服務調用,執行完畢後,-1。如果已經達到閾值,則直接fallback。
相比線程池,好處是沒有線程切換的開銷。壞處就是一旦達到閾值,就直接fallback,不像線程池還有個隊列可以緩衝一下
熔斷
有三個狀態:
1、 關,執行請求,收集執行情況。
2、 開,拒絕請求。根據執行失敗與執行總數的比值,也即服務健康狀況,與設定的閾值的比較,決定斷路器是否打開。默認是錯誤超50%,且10秒內超過20個請求。
3、 半開半關,經過一段時間後,允許某請求通過並執行,如成功,則關閉斷路器,反之繼續打開斷路器。
命令模式
基於命令模式,Hystrix將要執行請求的服務,封裝到HystrixCommand或HystrixObservableCommand中,這裡除了run()來執行具體的服務調用外,還包括線程池,斷路器,getFallback()失敗回調方法。
執行的流程:
1、 創建Command對象,執行調用。
2、 檢查斷路器是否開啟。根據Metrics決定斷路器的開關。
2.1、是,執行fallback。
2.2、否,進入3。
3、 檢查線程池是否已滿,並上報結果到Metrics。
3.1、是,執行fallback。
3.2、否,進入4。
4、 執行run()。
5、 檢查執行是否失敗,並上報結果到Metrics。
5.1、是,執行fallback。
5.2、否,進入6。
6、 檢查執行是否超時。並上報結果到Metrics。
6.1、是,執行fallback。
6.2、否,至此執行成功,返回結果。
7、 檢查fallback是否成功。
7.1、是,返回fallback結果。
7.2、否,拋異常。
斷路器
TAG:Java個人學習心得 |