1. 程式人生 > >微服務 Spring Boot 2.0 + Spring cloud + consul + Hystrix + zuul + config + feign (四)

微服務 Spring Boot 2.0 + Spring cloud + consul + Hystrix + zuul + config + feign (四)

 系列文章:

你知道雪崩效應嗎?

在微服務架構中,最可怕的就是這樣的情況:

  1. 當一個基礎的服務(A )出現了問題,比如資料庫
  2. 提供資料的服務(B)就不可用,
  3. 隨著時間的推移,
  4. 取票服務(C) 服務呼叫提供資料的服務(B)介面時,請求超時,C服務不可用
  5. 整個微服務系統奔潰

一張圖應該就可以明白:

那麼我們如何避免雪崩效應的產生?

spring cloud 給我們提供了作用在客戶端的 Hystrix 斷路保護機制。

Hystrix是一個有關延遲和失敗容錯的開源庫包,用來設計隔離訪問遠端系統端點或微服務等,防止級聯爆炸式的失敗,也就是由一個小問題引起接二連三擴大的瘋狂的錯誤爆炸直至整個系統癱瘓,能夠讓複雜的分散式系統更加靈活具有彈性。

先來張原理圖理解下吧:

  1. 是否快取
  2. 斷路器是否開啟
  3. 執行緒池是否充足

Hystrix是一個Java類庫, 它提供下面這些功能來幫助我們構建健壯的微服務系統:

  • 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)來隔離資源

Hystrix 的設計原則:

  • 防止單個服務的故障,耗盡整個系統服務的容器(比如tomcat)的執行緒資源。
  • 減少負載並快速失敗,而不是排隊。
  • 在可行的情況下提供回退以保護使用者免受故障。
  • 使用隔離技術(如隔板,泳道和斷路器模式)來限制任何一個依賴的影響。
  • 通過近乎實時的指標,監控和警報來優化發現故障的時間。
  • 通過配置更改的低延遲傳播優化恢復時間,並支援Hystrix大多數方面的動態屬性更改,從而允許您使用低延遲反饋迴圈進行實時操作修改。
  • 保護整個依賴客戶端執行中的故障,而不僅僅是在網路流量上進行保護降級、限流

體現設計原則:

  • 通過HystrixCommand 或者HystrixObservableCommand 將所有的外部系統(或者稱為依賴)包裝起來,整個包裝物件是單獨執行在一個執行緒之中(這是典型的命令模式)。
  • 超時請求應該超過你定義的閾值
  • 為每個依賴關係維護一個小的執行緒池(或訊號量); 如果它變滿了,那麼依賴關係的請求將立即被拒絕,而不是排隊等待。
  • 統計成功,失敗(由客戶端丟擲的異常),超時和執行緒拒絕。
  • 開啟斷路器可以在一段時間內停止對特定服務的所有請求,如果服務的錯誤百分比通過閾值,手動或自動的關閉斷路器。
  • 當請求被拒絕、連線超時或者斷路器開啟,直接執行fallback邏輯。
  • 近乎實時監控指標和配置變化。

Spring Cloud Client 端加入 Hystrix 端支援:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

        

application 加上  @EnableHystrix 

將需要hystrix 監控的方法加上註解 @HystrixCommand

    @GetMapping(value = "/call")
    @HystrixCommand
    public String call(){
        String msg = template.getForObject("http://consul-provider/provider",String.class);
        return msg;
    }