一、為什么要使用熔斷器?
在微服務架構中通常會有多個服務層調用,基礎服務的故障可能會導致級聯故障,進而造成整個系統不可用的情況,這種現象被稱為服務雪崩效應。服務雪崩效應是一種因“服務提供者”的不可用導致“服務消費者”的不可用,並將不可用逐漸放大的過程。Hystrix組件來進行容錯處理。Hystrix是Netflix的一款開源組件,它通過熔斷模式、隔離模式、回退(fallback)和限流等機制對服務進行彈性容錯保護,保證系統的穩定性。
如果下圖所示:A作為服務提供者,B為A的服務消費者,C和D是B的服務消費者。A不可用引起了B的不可用,並將不可用像滾雪球一樣放大到C和D時,雪崩效應就形成了。

二、什么是Hystrix
1. 介紹
Hystrix [hɪst'rɪks]的中文含義是豪豬, 因其背上長滿了刺,而擁有自我保護能力

2. 原理
Hystrix 能使你的系統在出現依賴服務失效的時候,通過隔離系統所依賴的服務,防止服務級聯失敗,同時提供失敗回退機制,更優雅地應對失效,並使你的系統能更快地從異常中恢復。

3. 功能
1、熔斷模式:熔斷模式原理類似於電路熔斷器,當電路發生短路時,熔斷器熔斷,保護電路避免遭受災難性損失。
當服務異常或者大量延時,滿足熔斷條件時服務調用方會主動啟動熔斷,執行fallback邏輯直接返回,不會繼續調用服務進一步拖垮系統。熔斷器默認配置服務調用錯誤率閥值為50%,超過閥值將自動啟動熔斷模式。服務隔離一段時間以后,熔斷器會進入半熔斷狀態,即允許少量請求進行嘗試,如果仍然調用失敗,則回到熔斷狀態,如果調用成功,則關閉熔斷模式。
2、隔離模式:Hystrix默認采用線程隔離,不同的服務使用不同的線程池,彼此之間不受影響,當一個服務出現故障耗盡它的線程池資源,其他的服務正常運行不受影響,達到隔離的效果。例如我們通過andThreadPoolKey配置某個服務使用命名為TestThreadPool的線程池,實現與其他命名的線程池隔離。
3、回退(fallback):fallback機制其實是一種服務故障時的容錯方式,原理類似Java中的異常處理。只需要繼承HystixCommand並重寫getFallBack()方法,在此方法中編寫處理邏輯,比如可以直接拋異常(快速失敗),可以返回空值或缺省值,也可以返回備份數據等。當服務調用出現異常時,會轉向執行getFallBack()。有以下幾種情況會觸發fallback:
程序拋出非HystrixBadRequestExcepption異常,當拋出HystrixBadRequestExcepption異常時,調用程序可以捕獲異常,沒有觸發fallback,當拋出其他異常時,會觸發fallback;
程序運行超時;
熔斷啟動;
線程池已滿。
4、限流: 限流是指對服務的並發訪問量進行限制,設置單位時間內的並發數,超出限制的請求拒絕並fallback,防止后台服務被沖垮。
Hystix使用命令模式HystrixCommand包裝依賴調用邏輯,這樣相關的調用就自動處於Hystrix的彈性容錯保護之下。調用程序需要繼承HystrixCommand並將調用邏輯寫在run()中,使用execute()(同步阻塞)或queue()(異步非阻塞)來觸發執行run()。
三、Hystrix的使用:
Hystrix雖然已經停止更新迭代,進入了維護階段,替代品Resilience4j成為了首先,但是遺留系統還有必要維護更新的。
Hystrix在項目中經常使用的方式主要有三種方式在;
1、繼承HystrixCommand實現代理類,把之前的業務邏輯寫在run()方法內
代碼示例詳見:https://github.com/Netflix/Hystrix/wiki/How-To-Use
而且支持同步執行、異步執行(返回Future)及響應式編程方式執行(返回Observable)。
這種適用於大量的方法需要熔斷處理,官方給了封裝的類庫:https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica,aop方式比較簡單,省去了大量的重復性的代碼量。
spring cloud環境下會幫我們自動配置:
3、feign 結合Hystrix
如果使用spring cloud微服務棧的話,feign是一般要使用的,所以feign自帶了組件:https://github.com/OpenFeign/feign/tree/master/hystrix
當然為了性能feign也支持異步返回。返回的對象支持:HystrixCommand<T>、Observable<T>、Single<T>、
CompletableFuture<T>、T。
具體可以看源碼:feign.hystrix.HystrixInvocationHandler 的實現:
參考:https://www.jianshu.com/p/271e287e5f01,https://blog.csdn.net/doctor_who2004/article/details/105475843