spring-cloud + 熔斷器 Hystrix + Demo

轉載自:http://www.ityouknow.com/springcloud/2017/05/16/springcloud-hystrix.html

其他參考:https://blog.csdn.net/u012482647/article/details/78148447

雪崩效應

在微服務架構中通常會有多個服務層調用,基礎服務的故障可能會導致級聯故障,進而造成整個系統不可用的情況,這種現象被稱爲服務雪崩效應。服務雪崩效應是一種因“服務提供者”的不可用導致“服務消費者”的不可用,並將不可用逐漸放大的過程。

如果下圖所示:A作爲服務提供者,B爲A的服務消費者,C和D是B的服務消費者。A不可用引起了B的不可用,並將不可用像滾雪球一樣放大到C和D時,雪崩效應就形成了。

熔斷器(CircuitBreaker)

熔斷器的原理很簡單,如同電力過載保護器。它可以實現快速失敗,如果它在一段時間內偵測到許多類似的錯誤,會強迫其以後的多個調用快速失敗,不再訪問遠程服務器,從而防止應用程序不斷地嘗試執行可能會失敗的操作,使得應用程序繼續執行而不用等待修正錯誤,或者浪費CPU時間去等到長時間的超時產生。熔斷器也可以使應用程序能夠診斷錯誤是否已經修正,如果已經修正,應用程序會再次嘗試調用操作。

熔斷器模式就像是那些容易導致錯誤的操作的一種代理。這種代理能夠記錄最近調用發生錯誤的次數,然後決定使用允許操作繼續,或者立即返回錯誤。 熔斷器開關相互轉換的邏輯如下圖:

熔斷器就是保護服務高可用的最後一道防線。

Hystrix特性

1.斷路器機制

斷路器很好理解, 當Hystrix Command請求後端服務失敗數量超過一定比例(默認50%), 斷路器會切換到開路狀態(Open). 這時所有請求會直接失敗而不會發送到後端服務. 斷路器保持在開路狀態一段時間後(默認5秒), 自動切換到半開路狀態(HALF-OPEN). 這時會判斷下一次請求的返回情況, 如果請求成功, 斷路器切回閉路狀態(CLOSED), 否則重新切換到開路狀態(OPEN). Hystrix的斷路器就像我們家庭電路中的保險絲, 一旦後端服務不可用, 斷路器會直接切斷請求鏈, 避免發送大量無效請求影響系統吞吐量, 並且斷路器有自我檢測並恢復的能力.

2.Fallback

Fallback相當於是降級操作. 對於查詢操作, 我們可以實現一個fallback方法, 當請求後端服務出現異常的時候, 可以使用fallback方法返回的值. fallback方法的返回值一般是設置的默認值或者來自緩存.

3.資源隔離

在Hystrix中, 主要通過線程池來實現資源隔離. 通常在使用的時候我們會根據調用的遠程服務劃分出多個線程池. 例如調用產品服務的Command放入A線程池, 調用賬戶服務的Command放入B線程池. 這樣做的主要優點是運行環境被隔離開了. 這樣就算調用服務的代碼存在bug或者由於其他原因導致自己所在線程池被耗盡時, 不會對系統的其他服務造成影響. 但是帶來的代價就是維護多個線程池會對系統帶來額外的性能開銷. 如果是對性能有嚴格要求而且確信自己調用服務的客戶端代碼不會出問題的話, 可以使用Hystrix的信號模式(Semaphores)來隔離資源.

Feign Hystrix

因爲熔斷只是作用在服務調用這一端,因此我們根據上一篇的示例代碼只需要改動spring-cloud-consumer項目相關代碼就可以。因爲,Feign中已經依賴了Hystrix所以在maven配置上不用做任何改動。

1、配置文件

application.properties添加這一條:

feign.hystrix.enabled=true

2、創建回調類

創建HelloRemoteHystrix類繼承與HelloRemote實現回調的方法

@Component
public class HelloRemoteHystrix implements HelloRemote{

    @Override
    public String hello(@RequestParam(value = "name") String name) {
        return "hello" +name+", this messge send failed ";
    }
}

3、添加fallback屬性

HelloRemote類添加指定fallback類,在服務熔斷的時候返回fallback類中的內容。

@FeignClient(name= "spring-cloud-producer",fallback = HelloRemoteHystrix.class)
public interface HelloRemote {

    @RequestMapping(value = "/hello")
    public String hello(@RequestParam(value = "name") String name);

}

改動點就這點,很簡單吧。

4、測試

那我們就來測試一下看看效果吧。

依次啓動spring-cloud-eureka、spring-cloud-producer、spring-cloud-consumer三個項目。

瀏覽器中輸入:http://localhost:9001/hello/neo

返回:hello neo,this is first messge

說明加入熔斷相關信息後,不影響正常的訪問。接下來我們手動停止spring-cloud-producer項目再次測試:

瀏覽器中輸入:http://localhost:9001/hello/neo

返回:hello neo, this messge send failed

根據返回結果說明熔斷成功。

示例代碼-github

示例代碼-碼雲

參考:

使用Spring Cloud與Docker實戰微服務

微服務框架Spring Cloud介紹 Part5: 在微服務系統中使用Hystrix, Hystrix Dashboard與Turbine

延伸閱讀1:雪崩

參考:https://www.jianshu.com/p/0a93fd0e608a

雪崩效應常見場景

  • 硬件故障:如服務器宕機,機房斷電,光纖被挖斷等。
  • 流量激增:如異常流量,重試加大流量等。
  • 緩存穿透:一般發生在應用重啓,所有緩存失效時,以及短時間內大量緩存失效時。大量的緩存不命中,使請求直擊後端服務,造成服務提供者超負荷運行,引起服務不可用。
  • 程序BUG:如程序邏輯導致內存泄漏,JVM長時間FullGC等。
  • 同步等待:服務間採用同步調用模式,同步等待造成的資源耗盡。

雪崩效應應對策略

針對造成雪崩效應的不同場景,可以使用不同的應對策略,沒有一種通用所有場景的策略,參考如下:

  • 硬件故障:多機房容災、異地多活等。
  • 流量激增:服務自動擴容、流量控制(限流、關閉重試)等。
  • 緩存穿透:緩存預加載、緩存異步加載等。
  • 程序BUG:修改程序bug、及時釋放資源等。
  • 同步等待:資源隔離、MQ解耦、不可用服務調用快速失敗等。資源隔離通常指不同服務調用採用不同的線程池;不可用服務調用快速失敗一般通過超時機制,熔斷器以及熔斷後降級方法等方案實現。

綜上所述,如果一個應用不能對來自依賴的故障進行隔離,那該應用本身就處在被拖垮的風險中。 因此,爲了構建穩定、可靠的分佈式系統,我們的服務應當具有自我保護能力,當依賴服務不可用時,當前服務啓動自我保護功能,從而避免發生雪崩效應。

 

 

 

 

 

 

 

 

 

發佈了40 篇原創文章 · 獲贊 1 · 訪問量 3428
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章