springcloud之hystrix原理和實踐總結

曹大聖發表於2020-12-23

目錄

Hystrix

解決什麼問題

hystrix的方案和設計原則

 

原理解析

hystrix流程圖

Maven整合

基本使用程式碼

command執行

requestcache

斷路器開關

hystrix隔離

fallback



Hystrix

解決什麼問題

分散式微服務系統以來很多子服務,每個子系統都可能出現故障和錯誤,如果服務不相互隔離,那麼每個服務的錯誤都可能壓垮其他服務,導致服務雪崩。

假設每個服務的可用性為9999,那麼30個子服務的整體可用性為

99.9930 = 99.7% uptime
0.3% of 1 billion requests = 3,000,000 failures
2+ hours downtime/month even if all dependencies have excellent uptime.

hystrix的方案和設計原則

  1. 熔斷器模式和設定超時時間,防止任何單一依賴關係耗盡所有容器(Tomcat)使用者執行緒。
  2. 減少負載和快速失敗,而不是排隊,每個服務設定執行緒池或者訊號量隔離,滿了直接拒絕而不是排隊
  3. 異常回退機制,在可行的情況下提供後備方案,以保護使用者不發生故障。
  4. 命令模式,使用隔離技術(如斷路器模式)來限制任何一個依賴的影響。
  5. 監控和統計呼叫資訊,優化故障發現時間,通過接近實時的度量、監視和報警。
  6. 動態配置修改,優化故障恢復時間,通過配置實時的配置修改生效

 

 

原理解析

hystrix流程圖

 

Maven整合

<dependency>

    <groupId>com.netflix.hystrix</groupId>

    <artifactId>hystrix-core</artifactId>

    <version>1.5.12</version>

</dependency>

 

基本使用程式碼

public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        // a real example would do work like a network call here
        return "Hello " + name + "!";
    }
}

command執行

  • execute() — 阻塞式呼叫command,execute() 呼叫queue().get().
  • queue() —非同步呼叫 queue() 呼叫toObservable().toBlocking().toFuture().
  • observe() — 呼叫toObservable()後直接訂閱,hystrix的核心呼叫流程都是基於rxjava實現的,關於observable的使用,可以參考rxjava的文件,後面將專門介紹rxjava的原理和使用。
  • toObservable() —只變成observable物件不訂閱,需要等呼叫方訂閱後生效,可以看到以上幾種方法都是基於這個方法實現的。

requestcache

是請求上下文作用域的,需要初始化contxt

HystrixRequestContext context = HystrixRequestContext.initializeContext();

and then this at the end of the request:

context.shutdown();

斷路器開關

 

如果錯誤率達到閾值會將斷路器開啟,請求直接返回異常走fallback

斷路器會通過所有commandmetrics資訊,失敗率,超時率等資訊,進行自動開發和關閉。Metrics資訊是按照桶統計的,每個桶代表一段時間,通過配置固定桶的個數,通過滑動時間視窗實現統計固定時間視窗的統計資訊。

 

hystrix隔離

使用執行緒池或者訊號量進行,如果達到訊號量閾值或者執行緒池滿了就直接拒絕走fallback邏輯

執行緒池和訊號量隔離區別:

  1. 執行緒池
    1. 不會阻塞呼叫執行緒,如tomcat
    2. 可以實現非同步呼叫或者併發呼叫
    3. 帶來執行緒切換開銷
    4. 請求排隊時延,佇列大小盡量接近0
    5. 執行緒池的配置問題:p99.5th耗時*qps
  2. 訊號量
    1. 基於javasemaphore,消耗低
    2. 只能限制併發量,在呼叫執行緒執行,會阻塞呼叫方

fallback

執行command的run方法,成功則返回結果,失敗則呼叫fallback邏輯,fallback執行失敗的話返回異常給呼叫執行緒

  1. 業務層面中斷任務執行,在底層是否中斷是不確定的,hystrix只能丟擲interuptexception,是否能中斷執行緒執行要看執行任務的執行緒是否響應intteruptexception異常,如果不響應是不會釋放執行緒。
  2. Fallback可以執行返回null,預設值,輸出日誌,告警,呼叫降級服務等操作,不要丟擲異常
  3. Fallback可以執行忽略異常: ignoreExceptions屬性,使用這個配置,如果丟擲被配置的異常,不會被統計到異常metrics中,直接返回badrequest異常
  4. hystrix基於 RxJava onErrorResumeNext 操作符無縫的實現原始observable和fallback observable之間的傳遞和變換

 

 

 

相關文章