Spring Cloud Spring Boot mybatis 企業分散式微服務雲(八)服務容錯保護(Hystrix依賴隔離)【Dalston版】

allalongx發表於2018-02-08

依賴隔離

艙壁模式”對於熟悉Docker的讀者一定不陌生,Docker通過“艙壁模式”實現程式的隔離,使得容器與容器之間不會互相影響。而Hystrix則使用該模式實現執行緒池的隔離,它會為每一個Hystrix命令建立一個獨立的執行緒池,這樣就算某個在Hystrix命令包裝下的依賴服務出現延遲過高的情況,也只是對該依賴服務的呼叫產生影響,而不會拖慢其他的服務。

通過對依賴服務的執行緒池隔離實現,可以帶來如下優勢:

應用自身得到完全的保護,不會受不可控的依賴服務影響。即便給依賴服務分配的執行緒池被填滿,也不會影響應用自身的額其餘部分。 可以有效的降低接入新服務的風險。如果新服務接入後執行不穩定或存在問題,完全不會影響到應用其他的請求。 當依賴的服務從失效恢復正常後,它的執行緒池會被清理並且能夠馬上恢復健康的服務,相比之下容器級別的清理恢復速度要慢得多。 當依賴的服務出現配置錯誤的時候,執行緒池會快速的反應出此問題(通過失敗次數、延遲、超時、拒絕等指標的增加情況)。同時,我們可以在不影響應用功能的情況下通過實時的動態屬性重新整理(後續會通過Spring Cloud Config與Spring Cloud Bus的聯合使用來介紹)來處理它。 當依賴的服務因實現機制調整等原因造成其效能出現很大變化的時候,此時執行緒池的監控指標資訊會反映出這樣的變化。同時,我們也可以通過實時動態重新整理自身應用對依賴服務的閾值進行調整以適應依賴方的改變。 除了上面通過執行緒池隔離服務發揮的優點之外,每個專有執行緒池都提供了內建的併發實現,可以利用它為同步的依賴服務構建非同步的訪問。 總之,通過對依賴服務實現執行緒池隔離,讓我們的應用更加健壯,不會因為個別依賴服務出現問題而引起非相關服務的異常。同時,也使得我們的應用變得更加靈活,可以在不停止服務的情況下,配合動態配置重新整理實現效能配置上的調整。

雖然執行緒池隔離的方案帶了如此多的好處,但是很多使用者可能會擔心為每一個依賴服務都分配一個執行緒池是否會過多地增加系統的負載和開銷。對於這一點,使用者不用過於擔心,因為這些顧慮也是大部分工程師們會考慮到的,Netflix在設計Hystrix的時候,認為執行緒池上的開銷相對於隔離所帶來的好處是無法比擬的。同時,Netflix也針對執行緒池的開銷做了相關的測試,以證明和打消Hystrix實現對效能影響的顧慮。

下圖是Netflix Hystrix官方提供的一個Hystrix命令的效能監控,該命令以每秒60個請求的速度(QPS)向一個單服務例項進行訪問,該服務例項每秒執行的執行緒數峰值為350個。

Spring Cloud Spring Boot mybatis 企業分散式微服務雲(八)服務容錯保護(Hystrix依賴隔離)【Dalston版】

從圖中的統計我們可以看到,使用執行緒池隔離與不使用執行緒池隔離的耗時差異如下表所示:

比較情況 未使用執行緒池隔離 使用了執行緒池隔離 耗時差距 中位數 2ms 2ms 2ms 90百分位 5ms 8ms 3ms 99百分位 28ms 37ms 9ms 在99%的情況下,使用執行緒池隔離的延遲有9ms,對於大多數需求來說這樣的消耗是微乎其微的,更何況為系統在穩定性和靈活性上所帶來的巨大提升。雖然對於大部分的請求我們可以忽略執行緒池的額外開銷,而對於小部分延遲本身就非常小的請求(可能只需要1ms),那麼9ms的延遲開銷還是非常昂貴的。實際上Hystrix也為此設計了另外的一個解決方案:訊號量。

Hystrix中除了使用執行緒池之外,還可以使用訊號量來控制單個依賴服務的併發度,訊號量的開銷要遠比執行緒池的開銷小得多,但是它不能設定超時和實現非同步訪問。所以,只有在依賴服務是足夠可靠的情況下才使用訊號量。在HystrixCommand和HystrixObservableCommand中2處支援訊號量的使用:

命令執行:如果隔離策略引數execution.isolation.strategy設定為SEMAPHORE,Hystrix會使用訊號量替代執行緒池來控制依賴服務的併發控制。 降級邏輯:當Hystrix嘗試降級邏輯時候,它會在呼叫執行緒中使用訊號量。 訊號量的預設值為10,我們也可以通過動態重新整理配置的方式來控制併發執行緒的數量。對於訊號量大小的估算方法與執行緒池併發度的估算類似。僅訪問記憶體資料的請求一般耗時在1ms以內,效能可以達到5000rps,這樣級別的請求我們可以將訊號量設定為1或者2,我們可以按此標準並根據實際請求耗時來設定訊號量。

如何使用

說了那麼多依賴隔離的好處,那麼我們如何使用Hystrix來實現依賴隔離呢?其實,我們在上一篇定義服務降級的時候,已經自動的實現了依賴隔離。

在上一篇的示例中,我們使用了@HystrixCommand來將某個函式包裝成了Hystrix命令,這裡除了定義服務降級之外,Hystrix框架就會自動的為這個函式實現呼叫的隔離。所以,依賴隔離、服務降級在使用時候都是一體化實現的,這樣利用Hystrix來實現服務容錯保護在程式設計模型上就非常方便的,並且考慮更為全面。除了依賴隔離、服務降級之外,還有一個重要元素:斷路器。我們將在下一篇做詳細的介紹,這三個重要利器構成了Hystrix實現服務容錯保護的強力組合拳。

Spring Cloud Spring Boot mybatis 企業分散式微服務雲(八)服務容錯保護(Hystrix依賴隔離)【Dalston版】
原始碼來源:http://minglisoft.cn/honghu/technology.html

相關文章