Hystrix詳述(一)

1、hystrix的做用git

  • 控制被依賴服務的延時和失敗
  • 防止在複雜系統中的級聯失敗
  • 能夠進行快速失敗(不須要等待)和快速恢復(當依賴服務失效後又恢復正常,其對應的線程池會被清理乾淨,即剩下的都是未使用的線程,相對於整個 Tomcat 容器的線程池被佔滿須要耗費更長時間以恢復可用來講,此時系統能夠快速恢復)
  • getFallback(失敗時指定的操做)和優雅降級
  • 實現近實時的檢測、報警、運維

2、hystrix實現中須要注意的點github

  • 爲每個依賴服務維護一個線程池(或者信號量),當線程池佔滿+queueSizeRejectionThreshold佔滿,該依賴服務將會當即拒絕服務而不是排隊等待
  • 引入『熔斷器』機制,在依賴服務失效比例超過閾值時,手動或者自動地切斷服務一段時間
  • 當請求依賴服務時出現拒絕服務、超時或者短路(多個依賴服務順序請求,前面的依賴服務請求失敗,則後面的請求不會發出)時,執行該依賴服務的失敗回退邏輯

3、hystrix線程模型緩存

  • 爲每個服務提供一個線程池,線程池數量能夠配置。(每一個Netflix API實例有超過 40 個線程池,每一個線程池有 5 到 20 個工做線程(絕大部分設置爲 10 個線程))
  • 每一個依賴服務都被隔離開來,Hystrix 會嚴格控制其在延遲發生時對資源的佔用,並在任何失效發生時,執行失敗回退邏輯
    • 注意:隔離是很是好的,隔離後,延時的被調用服務只會耗盡本身的線程池,以後進入失敗,見下圖(附:清晰大圖);若是不隔離,可能會耗盡整個tomcat的線程池,致使整個系統癱瘓。
  • tomcat線程(即調用線程)將請求接過來後,交給被依賴服務本身的線程池中的線程去執行(此時調用線程就能夠去作其餘的事情了,這與mina2的線程模型有類似之處)

 

4、hystrix執行流程(工做機理)tomcat

附:清晰大圖運維

步驟:(配合上圖去看)ui

一、構建HystrixCommand或者HystrixObservableCommand對象線程

二、執行命令(execute()、queue()、observe())得到返回結果(僅僅是得到,並無返回給調用端)翻譯

三、若是請求結果緩存這個特性被啓用,而且緩存命中,則緩存的迴應會當即經過一個 Observable 對象的形式返回。日誌

四、檢查熔斷器狀態,肯定請求線路是不是開路,若是請求線路是開路,Hystrix 將不會執行這個命令,而是直接使用『失敗回退邏輯』(即不會執行run(),直接執行getFallback())code

五、若是和當前須要執行的命令相關聯的線程池和請求隊列(或者信號量,若是不使用線程池)滿了,Hystrix 將不會執行這個命令,而是直接使用『失敗回退邏輯』(即不會執行run(),直接執行getFallback())

六、執行HystrixCommand.run()或HystrixObservableCommand.construct(),若是這兩個方法執行超時或者執行失敗,則執行getFallback();若是正常結束,Hystrix 在添加一些日誌和監控數據採集以後,直接返回迴應

七、Hystrix 會將請求成功,失敗,被拒絕或超時信息報告給熔斷器,熔斷器維護一些用於統計數據用的計數器。

這些計數器產生的統計數據使得熔斷器在特定的時刻,能短路某個依賴服務的後續請求,直到恢復期結束,若恢復期結束根據統計數據熔斷器斷定線路仍然未恢復健康,熔斷器會再次關閉線路。

 

 

5、熔斷器執行流程(工做機理)

附:清晰大圖

一、假設線路內的容量(請求QPS)達到必定閾值(經過 HystrixCommandProperties.circuitBreakerRequestVolumeThreshold() 配置),同時,假設線路內的錯誤率達到必定閾值(經過 HystrixCommandProperties.circuitBreakerErrorThresholdPercentage() 配置)

二、熔斷器將從『閉路』轉換成『開路』

三、若此時是『開路』狀態,熔斷器將短路後續全部通過該熔斷器的請求,這些請求直接走『失敗回退邏輯』(即不走run(),直接走getFallback())

四、通過必定時間(即『休眠窗口』,經過 HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds() 配置),後續第一個請求將會被容許經過熔斷器(此時熔斷器處於『半開』狀態),若該請求失敗,熔斷器將又進入『開路』狀態,且在休眠窗口內保持此狀態;若該請求成功,熔斷器將進入『閉路』狀態,回到邏輯1循環往復。

 

6、線程池與信號量

使用場景:對於那些原本延遲就比較小的請求(例如訪問本地緩存成功率很高的請求)來講,線程池帶來的開銷是很是高的,這時,你能夠考慮採用其餘方法,例如非阻塞信號量(不支持超時),來實現依賴服務的隔離,使用信號量的開銷很小。但絕大多數狀況下,Netflix 更偏向於使用線程池來隔離依賴服務,由於其帶來的額外開銷能夠接受,而且能支持包括超時在內的全部功能。

若是你對客戶端庫有足夠的信任(延遲不會太高),而且你只須要控制系統負載,那麼你可使用信號量。

 

7、請求合併

 

參考:

https://github.com/Netflix/Hystrix/wiki

http://youdang.github.io/categories/%E7%BF%BB%E8%AF%91/ 對官網翻譯的很是好,惋惜沒有翻譯完

相關文章
相關標籤/搜索