1. 程式人生 > 其它 >Spring-Cloud之Hystrix

Spring-Cloud之Hystrix

原文地址:https://blog.vchar.top/java/1624363200.html

系統負載過高,突發流量或網路等各種異常情況,常用解決方案如下:

  • 限流:對訪問量進行限制,防止流量太大直接使整個服務發生故障;
  • 熔斷:為了防止整個系統故障,停止出現問題的服務的訪問;
  • 降級:拋棄一些非核心的介面和資料;
  • 熔斷和降級互相交集:
    • 相同點:從可用性和可靠資訊出發,為防止系統崩潰;最終讓使用者體驗到的是某些功能暫時不可用
    • 不同點:服務熔斷一般是下游服務故障導致,而服務降級一般是從整個系統負荷考慮,由呼叫方控制

Hystrix的簡介

Netflix的Hystrix(豪豬)通過對呼叫的服務進行資源隔離,實現熔斷降級的功能,提升分散式系統的可用性和穩定性。

設計原則

hystrix為了實現高可用性的架構,設計hystrix的時候,遵循了以下這些設計原則:

  • 對依賴服務呼叫時出現的呼叫延遲和呼叫失敗進行控制和容錯保護;
  • 在複雜的分散式系統中,阻止某一個依賴服務的故障在整個系統中蔓延;如有如下呼叫鏈:服務A->服務B->服務C,當服務C發生故障時,如果沒做處理那麼服務B和服務A都會受到影響發生故障,導致整套分散式系統全部故障、整體宕機。
  • 提供fail-fast(快速失敗)和快速恢復的支援;
  • 提供fallback優雅降級的支援;
  • 支援近實時的監控、報警以及運維操作;

具體實現細節:

  • 阻止任何一個依賴服務耗盡所有的資源,比如tomcat中的所有執行緒資源
  • 避免請求排隊和積壓,採用限流和fail fast來控制故障
  • 提供fallback降級機制來應對故障
  • 使用資源隔離技術,比如Bulkhead(艙壁隔離技術),Swimlane(泳道技術),circuit breaker(短路技術),來限制任何一個依賴服務的故障的影響
  • 通過近實時的統計/監控/報警功能,來提高故障發現的速度
  • 通過近實時的屬性和配置熱修改功能,來提高故障處理和恢復的速度
  • 保護依賴服務呼叫的所有故障情況,而不僅僅只是網路故障情況

實現的方案的簡述

  • Hystrix通過外部依賴的訪問請求進行封裝,讓其執行在獨立的執行緒中達到資源隔離的目的;
  • 對請求的處理時間進行監控,如果超過設定的閥值那麼會直接讓其超時返回,不允許其耗費過長的時間阻塞住;
  • 為每個依賴服務維護一個獨立的執行緒池,當執行緒池滿了的時候就會直接拒絕這個服務的呼叫;
  • 統計依賴服務的呼叫情況,比如成功數、失敗數、拒絕次數、超時次數等;
  • 根據依賴服務的呼叫情況,自動判斷其健康狀態,如果失敗次數超過閥值自動進行熔斷(在一定時間內直接對該服務進行降級(也就是在呼叫的時候直接返回失敗),一段時間後再自動恢復嘗試);
  • 當一個服務調用出現失敗,被拒絕,超時,短路等異常情況時,自動呼叫fallback降級機制;
  • 對屬性和配置的修改提供近實時的支援;

這裡順便提一下:feign中它自己其實也有fallback降級機制(只是功能沒有那麼強大),比如如果依賴服務發生故障時雖然有fallback降級機制,但是還是會將請求向該服務傳送(該等待的時間依然會等待);

當我們引入Hystrix並啟用後,feign中的fallback降級機制將交給Hystrix來實現,而Hystrix會在監控到服務呼叫發生故障時,它會判斷其失敗次數,如果超過閥值,在一段時間內其它服務呼叫它的時候會直接返回降級處理策略,不會再向該服務傳送請求了。

Hystrix 使用示例

下面我們通過一些示例讓你快速瞭解它的基本使用。示例使用的Spring-Cloud的版本是Hoxton.SR8,Spring-Boot的版本是2.3.4.RELEASE。示例專案的原始碼

相關依賴和配置

新增如下maven的依賴(注意feign的請自行新增,feign的使用參考: https://blog.vchar.top/java/1621167133.html

<!-- hystrix的依賴-->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

然後在啟動類上新增如下註解:@EnableCircuitBreaker 或者是 @EnableHystrix ; 效果都是一樣的(@EnableHystrix繼承了@EnableCircuitBreaker註解)。

單獨使用 hystrix

通過新增@HystrixCommand註解可以讓該方法被hystrix監控到實現熔斷降級策略。

示例1:在controller中直接新增熔斷降級處理方式

@HystrixCommand(fallbackMethod = "hystrixMethodDemoFail")
    @GetMapping("/demo1")
    public Train findTrain(){
        System.out.println("執行...");
        // 這裡傳送異常時會自動執行hystrixMethodDemoFail方法
        return this.hystrixDemoService.hystrixMethodDemo();
    }

    /**
     * 這裡一定要和HystrixCommand註解中的方法一致,且引數也必須一致;當服務異常時會呼叫此方法
     */
    private Train hystrixMethodDemoFail(){
        System.out.println("呼叫異常");
        return null;
    }
}

示例2:在service中直接新增熔斷降級處理方式

@HystrixCommand(fallbackMethod = "hystrixMethodDemo2Fail")
@Override
public Train hystrixMethodDemo2() {
    System.out.println("hystrixMethodDemo2 呼叫feign服務:trainFeignClient.findTrain()");
    return this.trainFeignClient.findTrain();
}

private Train hystrixMethodDemo2Fail(){
    System.out.println("hystrixMethodDemo2Fail ...");
    return null;
}

示例3:方法間的呼叫

@Override
public Train hystrixMethodDemo3() {
    // hystrixMethodDemo2做了熔斷降級的
    return this.hystrixMethodDemo2();
}

因為hystrix是通過AOP來實現的;因此一個類的方法間呼叫時不會生效的。

結合feign使用hystrix

feign之前的寫法不用改變,繼續保持即可;只需要新增如下配置就可以將feign的熔斷降級處理的方式切換到hystrix:

feign:
  hystrix:
    # 啟用feign中的hystrix
    enabled: true

hystrix的監控介面

新增下面的maven依賴:

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

在啟動類上添加註解: @EnableHystrixDashboard ;然後新增如下配置:

management:
  endpoints:
    web:
      exposure:
        include: "*"

然後訪問監控介面:http://localhost:8100/hystrix ;在裡面輸入 http://localhost:8100/actuator/hystrix.stream 點選 Monitor Stream進入監控介面。