Spring Cloud Hystrix資源隔離策略(線程、信號量)


Hystrix 的資源隔離策略有兩種,分別為線程池和信號量。那我們為什么需要資源隔離呢?

在一個分布式系統中,服務之間都是相互調用的,例如,我們容器(Tomcat)配置的線程個數為 1000,服務 A-服務 R,其中服務 I 的並發量非常的大,需要 500 個線程來執行,此時,服務 I 又掛了,那么這 500 個線程很可能就夯死了,那么剩下的服務,總共可用的線程為 500 個,隨着並發量的增大,剩余服務掛掉的風險就會越來越大,最后導致整個系統的所有服務都不可用,直到系統宕機。

以上就是服務的雪崩效應。Hystrix 就是用來做資源隔離的,比如說,當客戶端向服務端發送請求時,給服務 I 分配了 10 個線程,只要超過了這個並發量就走降級服務,就算服務 I 掛了,最多也就導致服務 I 不可用,容器的 10 個線程不可用了,但是不會影響系統中的其他服務。

下面,我們就來具體說下這兩種隔離策略。

信號量策略配置

用於隔離本地代碼可快速返回的遠程調用可以直接使用信號量隔離,降低線程隔離的上下文切換開銷。如 memcached,redis。

線程隔離會帶來線程開銷,有些場景(比如無網絡請求場景)可能會因為用開銷換隔離得不償失,為此 hystrix 提供了信號量隔離

主要適用於並發需求不大的依賴調用,因為如果並發需求較大,相應的信號量的數量就要設置得夠大,因為 Tomcat 線程與處理線程為同一個線程,那么這個依賴調用就會占用過多的 Tomcat 線程資源,有可能會影響到其他服務的接收。

信號量策略配置方法代碼如下所示。

super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyGroup"))
        .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
            .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE
            )));
    this.name = name;
}

之前在 run 方法中特意輸出了線程名稱,通過這個名稱就可以確定當前是線程隔離還是信號量隔離。

線程隔離策略配置

執行依賴代碼的線程與請求線程(比如 Tomcat 線程)分離,請求線程可以自由控制離開的時間,這也是我們通常說的異步編程,Hystrix 是結合 RxJava 來實現的異步編程。

通過為每個包裹了 HystrixCommand 的 API 接口設置獨立的、固定大小的線程池(hystrix.threadpool.default.coreSize)來控制並發訪問量,當線程飽和的時候可以拒絕服務,防止依賴問題擴散。

系統默認采用線程隔離策略,我們可以通過 andThreadPoolPropertiesDefaults 配置線程池的一些參數,代碼如下所示。

public MyHystrixCommand(String name) {
    super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyGroup"))
            .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                    .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
            .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(10)
                    .withMaxQueueSize(100).withMaximumSize(100)));
    this.name = name;
}

線程隔離策略的優點如下:

  • 一個依賴調用可以給予一個線程池,這個依賴的異常不會影響其他的依賴。
  • 使用線程可以完全隔離業務代碼,請求線程可以快速返回。
  • 可以完全模擬異步調用,方便異步編程。

線程隔離策略的缺點:使用線程池的缺點主要是增加了計算的開銷。每一個依賴調用都會涉及到隊列,調度,上下文切換,而這些操作都有可能在不同的線程中執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM