SpringCloud的Hystrix(五) Hystrix機制


參考鏈接:http://www.jianshu.com/p/e07661b9bae8

 

一、前言

大型復雜的分布式系統中,高可用相關的技術架構非常重要。
高可用架構非常重要的一個環節,就是如何將分布式系統中的各個服務打造成高可用的服務,從而足以應對分布式系統環境中的各種各樣的問題,,避免整個分布式系統被某個服務的故障給拖垮。
比如:

  • 服務間的調用超時
  • 服務間的調用失敗

要解決這些棘手的分布式系統可用性問題,就涉及到了高可用分布式系統中的很多重要的技術,包括:

  • 資源隔離
  • 限流與過載保護
  • 熔斷
  • 優雅降級
  • 容錯
  • 超時控制
  • 監控運維

二、運行原理

Hystrix是國外知名的視頻網站Netflix所開源的非常流行的高可用架構框架。Hystrix能夠完美的解決分布式系統架構中打造高可用服務面臨的一系列技術難題。

Hystrix “豪豬”,具有自我保護的能力。hystrix 通過如下機制來解決雪崩效應問題。

  • 資源隔離:包括線程池隔離和信號量隔離,限制調用分布式服務的資源使用,某一個調用的服務出現問題不會影響其他服務調用。
  • 降級機制:超時降級、資源不足時(線程或信號量)降級,降級后可以配合降級接口返回托底數據。
  • 融斷:當失敗率達到閥值自動觸發降級(如因網絡故障/超時造成的失敗率高),熔斷器觸發的快速失敗會進行快速恢復。
  • 緩存:提供了請求緩存、請求合並實現。

Hystrix支持實時監控、報警、控制(修改配置)。

(1)線程池隔離模式:使用一個線程池來存儲當前請求,線程池對請求作處理,設置任務返回處理超時時間,堆積的請求先入線程池隊列。這種方式要為每個依賴服務申請線程池,有一定的資源消耗,好處是可以應對突發流量(流量洪峰來臨時,處理不完可將數據存儲到線程池隊里慢慢處理)
(2)信號量隔離模式:使用一個原子計數器(或信號量)記錄當前有多少個線程在運行,請求來先判斷計數器的數值,若超過設置的最大線程個數則丟棄該類型的新請求,若不超過則執行計數操作請求來計數器+1,請求返回計數器-1。這種方式是嚴格的控制線程且立即返回模式,無法應對突發流量(流量洪峰來臨時,處理的線程超過數量,其他的請求會直接返回,不繼續去請求依賴的服務)
 

熔斷

正常情況下,斷路器處於關閉狀態(Closed),
如果調用持續出錯或者超時,電路被打開進入熔斷狀態(Open),后續一段時間內的所有調用都會被拒絕(Fail Fast),
一段時間以后,保護器會嘗試進入半熔斷狀態(Half-Open),允許少量請求進來嘗試,
        如果調用仍然失敗,則回到熔斷狀態
        如果調用成功,則回到電路閉合狀態;

降級

服務降級的目的保證上游服務的穩定性,當整體資源快不夠了,將某些服務先關掉,待渡過難關,再開啟回來。
 

三、調用過程

工作流程(參考:https://github.com/Netflix/Hystrix/wiki/How-it-Works

1、 創建一個 HystrixCommand 或 HystrixObservableCommand 實例

第一步就是構建一個 HystrixCommand 或 HystrixObservableCommand 實例來向其它組件發出操作請求,通過構造方法來創建實例。

HystrixCommand:返回一個單響應

HystrixObservableCommand:返回一個觀察者發出的響應 

2、 執行方法

這里有4個方法,前兩個只適用於 HystrixCommand 不適用於 HystrixObservableCommand

execute():阻塞型方法,返回單個結果(或者拋出異常)

queue():異步方法,返回一個 Future 對象,可以從中取出單個結果(或者拋出異常)

  • observe():返回Observable 對象

toObservable():返回Observable 對象 

3、 緩存判斷

檢查緩存內是否有對應指令的結果,如果有的話,將緩存的結果直接以 Observable 對象的形式返回 

4、 斷路器判斷

檢查Circuit Breaker的狀態。如果Circuit Breaker的狀態為開啟狀態,Hystrix將不會執行對應指令,而是直接進入失敗處理狀態(圖中8)。如果Circuit Breaker的狀態為關閉狀態,Hystrix會繼續執行(圖5) 

5、 線程池、任務隊列、信號量的檢查

確認是否有足夠的資源執行操作指令。當線程池和隊列(或者是信號量,當不使用線程池隔離模式的時候)資源滿的時候,Hystrix將不會執行對應指令並且會直接進入失敗處理狀態(圖8) 

6、 HystrixObservableCommand.construct() 和 HystrixCommand.run()

如果資源充足,Hystrix將會執行操作指令。操作指令的調用最終都會到這兩個方法:

HystrixCommand.run():返回一個響應或者拋出一個異常

HystrixObservableCommand.construct():返回一個可觀測的發出響應(s)或發送一個onError通知 

如果執行指令的時間超時,執行線程會拋出 TimeoutException 異常。Hystrix會拋棄結果並直接進入失敗處理狀態。如果執行指令成功,Hystrix會進行一系列的數據記錄,然后返回執行的結果。 

7、 統計斷路器的健康情況

Hystrix會根據記錄的數據來計算失敗比率,一旦失敗比率達到某一閾值將自動開啟Circuit Breaker 

8、 回退

如果我們在Command中實現了HystrixCommand.getFallback()方法(或HystrixObservableCommand. resumeWithFallback() 方法,Hystrix會返回對應方法的結果。如果沒有實現這些方法的話,仍然 Hystrix會返回一個空的 Observable 對象,並且可以通過 onError 來終止並處理錯誤。    

調用不同的方法返回不同的結果:

execute(): 將會拋出異常

queue(): 將會返回一個Future 對象,如果調用它的get()方法將會拋出異常

  • observe()和 toObservable():都會返回上述的 Observable 對象 

9、 返回成功

如果Hystrix執行成功,返回的響應取決於在步驟2中調用命令。

execute():阻塞型方法,返回單個結果(或者拋出異常)

queue():異步方法,返回一個 Future 對象,可以從中取出單個結果(或者拋出異常)

  • observe():返回Observable 對象

toObservable():返回Observable 對象

斷路器的工作原理

斷路器開啟或者關閉的條件:

1、  當滿足一定的閥值的時候(默認10秒內超過20個請求次數)

2、  當失敗率達到一定的時候(默認10秒內超過50%的請求失敗)

3、  到達以上閥值,斷路器將會開啟

4、  當開啟的時候,所有請求都不會進行轉發

5、  一段時間之后(默認是5秒),這個時候斷路器是半開狀態,會讓其中一個請求進行轉發。如果成功,斷路器會關閉,若失敗,繼續開啟。重復4 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM