本篇學習Spring Cloud家族中的重要成員:Hystrix。分布式系統中一個服務可能依賴着很多其他服務,在高並發的場景下,如何保證依賴的某些服務如果出了問題不會導致主服務宕機這個問題就會變得異常重要。
針對這個問題直觀想到的解決方案就是做依賴隔離。將不同的依賴分配到不同的調用鏈中,某一條鏈發生失敗不會影響別的鏈。今天要說的Hystrix就提供了這樣的功能。Hystrix的作用就是處理服務依賴,幫助我們做服務治理和服務監控。
那么Hystrix是如何解決依賴隔離呢?從官網上看到這樣一段:
- Hystrix使用命令模式
HystrixCommand
(Command)包裝依賴調用邏輯,每個命令在單獨線程中/信號授權下執行。 - 可配置依賴調用超時時間,超時時間一般設為比99.5%平均時間略高即可.當調用超時時,直接返回或執行fallback邏輯。
- 為每個依賴提供一個小的線程池(或信號),如果線程池已滿調用將被立即拒絕,默認不采用排隊,加速失敗判定時間。
- 依賴調用結果分:成功,失敗(拋出異常),超時,線程拒絕,短路。 請求失敗(異常,拒絕,超時,短路)時執行fallback(降級)邏輯。
- 提供熔斷器組件,可以自動運行或手動調用,停止當前依賴一段時間(10秒),熔斷器默認錯誤率閾值為50%,超過將自動運行。
另外在學習之前大家需要注意的是,Hystrix現在已經停止更新,意味着你在生產環境如果想使用的話就要考慮現有功能是否能夠滿足需求。另外開源界現在也有別的更優秀的服務治理組件:Resilience4j 和 Sentinel,如果你有需要可以去看一下它們現在的使用情況。當然這里並不影響我們繼續學習Hystrix,畢竟作為分布式依賴隔離的鼻祖,它的設計思想還是需要吃透的。
Hystrix如何實現依賴隔離
命令模式
將所有請求外部系統(或者叫依賴服務)的邏輯封裝到 HystrixCommand 或者 HystrixObservableCommand 對象中。
Run()方法為實現業務邏輯,這些邏輯將會在獨立的線程中被執行當請求依賴服務時出現拒絕服務、超時或者短路(多個依賴服務順序請求,前面的依賴服務請求失敗,則后面的請求不會發出)時,執行該依賴服務的失敗回退邏輯(Fallback)。
隔離策略
Hystrix 為每個依賴項維護一個小線程池(或信號量);如果它們達到設定值(觸發隔離),則發往該依賴項的請求將立即被拒絕,執行失敗回退邏輯(Fallback),而不是排隊。
隔離策略分線程隔離和信號隔離。
-
線程隔離
第三方客戶端(執行Hystrix的run()方法)會在單獨的線程執行,會與調用的該任務的線程進行隔離,以此來防止調用者調用依賴所消耗的時間過長而阻塞調用者的線程。
使用線程隔離的好處:
- 應用程序可以不受失控的第三方客戶端的威脅,如果第三方客戶端出現問題,可以通過降級來隔離依賴。
- 當失敗的客戶端服務恢復時,線程池將會被清除,應用程序也會恢復,而不至於使整個Tomcat容器出現故障。
- 如果一個客戶端庫的配置錯誤,線程池可以很快的感知這一錯誤(通過增加錯誤比例,延遲,超時,拒絕等),並可以在不影響應用程序的功能情況下來處理這些問題(可以通過動態配置來進行實時的改變)。
- 如果一個客戶端服務的性能變差,可以通過改變線程池的指標(錯誤、延遲、超時、拒絕)來進行屬性的調整,並且這些調整可以不影響其他的客戶端請求。
簡而言之,由線程供的隔離功能可以使客戶端和應用程序優雅的處理各種變化,而不會造成中斷。
線程池的缺點
線程最主要的缺點就是增加了CPU的計算開銷,每個command都會在單獨的線程上執行,這樣的執行方式會涉及到命令的排隊、調度和上下文切換。
Netflix在設計這個系統時,決定接受這個開銷的代價,來換取它所提供的好處,並且認為這個開銷是足夠小的,不會有重大的成本或者是性能影響。
-
信號隔離
信號隔離是通過限制依賴服務的並發請求數,來控制隔離開關。信號隔離方式下,業務請求線程和執行依賴服務的線程是同一個線程(例如Tomcat容器線程)。
觀察者模式
- Hystrix通過觀察者模式對服務進行狀態監聽
- 每個任務都包含有一個對應的Metrics,所有Metrics都由一個ConcurrentHashMap來進行維護,Key是CommandKey.name()
- 在任務的不同階段會往Metrics中寫入不同的信息,Metrics會對統計到的歷史信息進行統計匯總,供熔斷器以及Dashboard監控時使用
Metrics
- Metrics內部又包含了許多內部用來管理各種狀態的類,所有的狀態都是由這些類管理的
- 各種狀態的內部也是用ConcurrentHashMap來進行維護的
Metrics在統計各種狀態時,時運用滑動窗口思想進行統計的,在一個滑動窗口時間中又划分了若干個Bucket(滑動窗口時間與Bucket成整數倍關系),滑動窗口的移動是以Bucket為單位進行滑動的。
熔斷機制
熔斷機制是一種保護性機制,當系統中某個服務失敗率過高時,將開啟熔斷器,對該服務的后續調用,直接拒絕,進行Fallback操作。
熔斷所依靠的數據即是Metrics中的HealthCount所統計的錯誤率。
如何判斷是否應該開啟熔斷器?
必須同時滿足兩個條件:
- 請求數達到設定的閥值;
- 請求的失敗數 / 總請求數 > 錯誤占比閥值%。
降級策略
當construct()或run()執行失敗時,Hystrix調用fallback執行回退邏輯,回退邏輯包含了通用的響應信息,這些響應從內存緩存中或者其他固定邏輯中得到,而不應有任何的網絡依賴。
如果一定要在失敗回退邏輯中包含網絡請求,必須將這些網絡請求包裝在另一個 HystrixCommand 或 HystrixObservableCommand 中,即多次降級。
失敗降級也有頻率限時,如果同一fallback短時間請求過大,則會拋出拒絕異常。
緩存機制
同一對象的不同HystrixCommand實例,只執行一次底層的run()方法,並將第一個響應結果緩存起來,其后的請求都會從緩存返回相同的數據。
由於請求緩存位於construct()或run()方法調用之前,所以,它減少了線程的執行,消除了線程、上下文等開銷。
一個Demo
首先引入jar包:
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.18</version>
</dependency>
如果我們有一個被依賴的服務想要被Hystrix封裝,繼而使用Hystrix提供的依賴隔離服務,使用方式很簡單,你只需要在你的實現類上繼承 HystrixCommand/HystrixObservableCommand
即可,重寫run()/construct()
,封裝你要調用的邏輯,然后調用該類執行 execute()/queue()/observe()/toObservable()
即可。
HystrixCommand
用於獲取只有一條返回結果的情況:
package com.rickiyang.learn.service;
import com.netflix.hystrix.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rx.Observable;
import java.util.concurrent.Future;
/**
* 一段簡單的使用HystrixCommand封裝服務隔離調用的實例
*/
public class QueryOrderIdCommand extends HystrixCommand<Integer> {
private final static Logger logger = LoggerFactory.getLogger(QueryOrderIdCommand.class);
private String orderId = "";
/**
* 構造函數中封裝了一些參數設置
* @param orderId
*/
public QueryOrderIdCommand(String orderId) {
super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("orderService"))
.andCommandKey(HystrixCommandKey.Factory.asKey("queryByOrderId"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withCircuitBreakerRequestVolumeThreshold(10)//至少有10個請求,熔斷器才進行錯誤率的計算
.withCircuitBreakerSleepWindowInMilliseconds(5000)//熔斷器中斷請求5秒后會進入半打開狀態,放部分流量過去重試
.withCircuitBreakerErrorThresholdPercentage(50)//錯誤率達到50開啟熔斷保護
)
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("orderServicePool"))
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties
.Setter().withCoreSize(10)));
this.orderId = orderId;
}
/**
* run 方法中是你真正想要執行邏輯的地方
* @return
*/
@Override
protected Integer run() {
return 1;
}
@Override
public Integer execute() {
Thread t = Thread.currentThread();
System.out.println("thread " + t.getName() + ": now " + orderId + " execute queue()...");
return super.execute();
}
@Override
public Future<Integer> queue() {
Thread t = Thread.currentThread();
System.out.println("thread " + t.getName() + ": now " + orderId + " execute queue()...");
return super.queue();
}
@Override
public Observable<Integer> observe() {
Thread t = Thread.currentThread();
System.out.println("thread " + t.getName() + ": now " + orderId + " execute observe()...");
return super.observe();
}
@Override
public Observable<Integer> toObservable() {
Thread t = Thread.currentThread();
System.out.println("thread " + t.getName() + ": now " + orderId + " execute toObservable()...");
return super.toObservable();
}
/**
* 如果發生失敗在這里寫回調的邏輯
* @return
*/
@Override
protected Integer getFallback() {
return -1;
}
/**
* 這里是簡單的模擬調用
* @param args
*/
public static void main(String[] args) {
Integer r = new QueryOrderIdCommand("1").execute();
logger.info("result:{}", r);
}
}
上面的代碼展示了HystrixCommand使用方式,在main函數中執行了 execute()方法,還有一個 queue,observe,toObservable 方法,其中 observe,toObservable方法是 HystrixObservableCommand 類 實現的,下面會說到。它們的區別是:
-
execute:同步堵塞,調用了queue().get()方法,execute()執行完后,會創建一個新線程運行run();
-
queue:異步非堵塞,它調用了toObservable().toBlocking().toFuture()方法,queue()執行完后,會創建一個新線程運行run()。Future.get()是堵塞的,它等待run()運行完才返回結果;
-
observe() :異步熱響應調用,它調用了toObservable().subscribe(subject)方法,observe()執行完后,會創建一個新線程運行run()。toBlocking().single()是堵塞的,需要等run()運行完才返回結果;
-
toObservable():異步的冷響應調用,該方法不會主動創建線程運行run(),只有當調用了toBlocking().single()或subscribe()時,才會去創建線程運行run()。
降級
HystrixCommand提供回退降級的方法:getFallback。在生產環境實現該方法的時候要注意該方法的響應要快盡量不要有網絡依賴,這樣才能保證降級一定是能成功。
假如說回退降級方法中還有網絡依賴,那么就有失敗的可能,這時候可以考慮多次降級,即在getFallback 方法調用中繼續實現 新的 HystrixCommand 邏輯,保證調用不會失敗。
熔斷
上面示例中的CircuitBreaker
設置就是跟熔斷器相關的參數。
需要注意的是設置的熔斷器參數是並的關系,即所有的熔斷器條件都滿足的情況下才會執行熔斷邏輯。比如按照我們上面的設置:
整個鏈路請求數達到閥值(circuitBreaker.requestVolumeThreshold
)=10,
並且請求的錯誤數比例大於閥值(circuitBreaker.errorThresholdPercentage
)= 50%,則會打開熔斷器。
如果熔斷器處於打開狀態,將會進入休眠期,在休眠期內,所有請求都將被拒絕,直接執行fallback邏輯。
根據 Metrics
的計算,可以判斷熔斷器的健康狀態,從而決定是否應該關閉熔斷器:
- 熔斷器被打開后,根據
circuitBreaker.sleepWindowInMilliseconds
設置,會休眠一段時間,這段時間內的所有請求,都直接fallback; - 休眠時間過后,Hystrix會將熔斷器狀態改為半開狀態,然后嘗試性的執行一次command,如果成功,則關閉熔斷器,如果失敗,繼續打開熔斷器,執行新的熔斷周期;
- 熔斷器打開后,熔斷器的健康檢查指標會重置,重新開始計算。
熔斷器有以下幾個特殊參數:
1、如果hystrix.command.default.circuitBreaker.enabled設置為false,將不使用斷路器來跟蹤健康狀況,也不會在斷路器跳閘時將其短路(即不會執行fallback)
2、如果hystrix.command.default.circuitBreaker.forceOpen設置為true,斷路器將強制打開,所有請求將被拒絕,直接進入fallback
3、如果hystrix.command.default.circuitBreaker.forceClosed設置為true,斷路器將強制關閉,無論錯誤百分比如何,都將允許請求(永遠會執行run)
HystrixCommand參數設置
上面在構造函數中設置了一些Hystrix執行邏輯的參數,分別解釋一下它們的含義:
- CommandKey/CommandName :是一個依賴服務的command標識;
- GroupKey:將報告,警報,儀表板或團隊/庫所有權等命令組合在一起。一般可以根據服務模塊或第三方客戶端來分配GroupKey,一個GroupKey下可以有多個CommandKey;
- ThreadPoolKey:用於監視,度量標准發布,緩存和其他此類用途的HystrixThreadPool。可以一個CommandKey綁定一個ThreadPoolKey用,這樣多個線程的CommandKey就會划分到同一個ThreadPoolKey。
沒有定義ThreadPoolKey時,ThreadPoolKey使用GroupKey,定義了ThreadPoolKey時,則使用定義值(采用線程策略隔離的情況下)。
command在執行run()時,會創建一個線程,該線程的名稱是ThreadPoolKey和序列號的組合,序列號是該線程在線程池中的創建順序。
使用ThreadPoolKey的原因是多個command可能屬於同一個所有權或邏輯功能『組』,但某些command又需要彼此隔離。
注意:
- 同一個HystrixCommand對象只能執行一次run();
- observe()中,toBlocking().single()與subscribe()是可以共存的,因為run()是在observe()中被調用的,只調用了一次;
- toObservable()中,toBlocking().single()與subscribe()不可共存,因為run()是在toBlocking().single()或subscribe()中被調用的;如果同時存在toBlocking().single()和subscribe(),相當於調用了2次run(),會報錯。
HystrixObservableCommand適用於可能會有多條數據返回的場景:
import com.netflix.hystrix.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.schedulers.Schedulers;
import java.util.concurrent.ExecutionException;
/**
* 一段簡單的使用HystrixCommand封裝服務隔離調用的實例
*/
public class QueryOrderIdOtherCommand extends HystrixObservableCommand<String> {
private final static Logger logger = LoggerFactory.getLogger(QueryOrderIdOtherCommand.class);
private final String name;
public QueryOrderIdOtherCommand(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected Observable<String> construct() {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> observer) {
try {
if (!observer.isUnsubscribed()) {
observer.onNext("Hello");
observer.onNext(name + "!");
observer.onCompleted();
}
} catch (Exception e) {
observer.onError(e);
}
}
} ).subscribeOn(Schedulers.io());
}
/**
* 這里是簡單的模擬調用
* @param args
*/
public static void main(String[] args) throws ExecutionException, InterruptedException {
QueryOrderIdOtherCommand command = new QueryOrderIdOtherCommand("1");
command.toObservable().subscribe(new Observer<String>() {
@Override
public void onCompleted() {
System.out.println("complate");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
System.out.println("1");
}
});
//HystrixObservableCommand不提供同步執行方法, 但是你想的話, 那么也可以用如下方式實現:
command.observe().toBlocking().toFuture().get();
command.toObservable().toBlocking().toFuture().get();
}
}
使用 HystrixObservableCommand
調用邏輯被封裝在contruct函數中,在這里用到了FxJava,后面會專門說一下為什么會在這里使用FxJava。
另外contruct函數中兩次調用了next方法,每一次next調用表示你當前執行業務邏輯一次,那么在main函數中調用方式在上例main函數中subscribe訂閱也會返回兩次的調用結果,onNext會被調用兩次。
使用toObservable方法默認是異步的方式調用,如果你想用同步的方式,也可以使用最后兩行代碼的方式進行調用。
隔離策略
隔離策略分 線程隔離 和 信號隔離。
HystrixCommand
默認采用的是線程隔離策略。當執行 construct()
或 run()
時,會創建一個線程。因為 Hystrix
用到了線程池,真實的流程是這樣的:
- 執行
construct()
或run()
時,先判斷線程池中是否有空閑的線程(每個Command都可以擁有自己的線程池而不會互相影響); - 如果沒有空閑的,則看當前線程數是否達到
hystrix.threadpool.default.coreSize
,如果達到,則需要排隊,當隊列值大於hystrix.threadpool.default.maxQueueSize
, 會拒絕請求,執行回退邏輯,如果沒有達到,則創建一個新的線程來執行; - 如果有空閑的,則直接從空閑的線程中取出一個來執行。
當然,我們也可以設置 hystrix.threadpool.default.maximumSize
,動態的控制線程的大小。該參數表示一個 HystrixCommand
可以創建的最大線程數,當線程池中的線程在 hystrix.threadpool.default.keepAliveTimeMinutes
時間內沒有使用,則會關閉一些線程,使線程數等於在 hystrix.threadpool.default.coreSize
。
注意:
必須將 hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize
設置為 true
時,hystrix.threadpool.default.maximumSize
才會生效.
hystrix.threadpool.default.coreSize
的默認值為10,如果需要提高此值,按照以下公式計算:
最大線程數 = QPS * 平均響應時間(單位秒)* 99% + 緩存數
舉例說明:
某個接口的單台服務器QPS為10000,平均響應時間為20ms
最大線程數:10000 * 0.02 * 0.99 + 4 = 202
Hystrix
官方建議盡量將最大線程數設置的小一些,因為它是減少負載並防止資源在延遲發生時被阻塞的主要工具。線程數能設置多大,有什么影響,這個需要根據自身業務情況和實際壓測結果來衡量。
信號隔離
HystrixObservableCommand
默認采用的是信號隔離。HystrixCommand
可以通過修改 hystrix.command.default.execution.isolation.strategy
參數調整為信號隔離。
- 信號隔離是對客戶端請求線程的並發限制,采用信號隔離時,hystrix的線程相關配置將無效
- 當請求並發量大於
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests
時,請求執行fallback - 當fallback的並發線程數大於
hystrix.command.default.fallback.isolation.semaphore.maxConcurrentRequests
時,fallback將拋異常fallback execution rejected
信號隔離策略下,執行 construct()
或 run()
時,使用的是應用服務的父級線程(如Tomcat容器線程)。所以,一定要設置好並發量,有網絡開銷的調用,不建議使用該策略,容易導致容器線程排隊堵塞,從而影響整個應用服務。
HystrixObservableCommand
與 HystrixCommand
的區別:
- 它們兩個是
Hystrix
執行Command的兩種方式; HystrixCommand
的執行封裝在run(),fallback處理封裝在getFallBack();HystrixObservableCommand
的執行封裝在contruct(),fallback處理封裝在resumeWithFallback();HystrixObservableCommand
使用的信號隔離策略,所以,使用的是應用服務的父級線程調用contruct();HystrixObservableCommand
在contruct()中可以定義多個onNext,當調用subscribe()注冊成功后,將依次執行這些onNext(),后者只能在run()中返回一個值(即一個onNext)。可以理解為HystrixCommand
一次只能發送單條數據返回,而HystrixObservableCommand
一次可以發送多條數據返回;- 同
HystrixCommand
一樣,HystrixObservableCommand
使用observe(),toBlocking().single()或subscribe()可以共存,而使用toObservable(),則不能共存。
線程池隔離技術和信號量隔離技術,分別在什么樣的場景下去使用?
- 線程池:適合99%場景,線程池一般處理對依賴服務的網絡請求的調用和訪問,timeout這種問題。
- 信號量:適合不是對外部依賴的訪問,而是對內部的一些比較復雜的業務邏輯的訪問,但是像這種訪問系統內部的代碼,其實不涉及任何的網絡請求。那么只要做信號量的普通限流就可以了,因為不需要去捕獲timeout類似的問題,如果算法+數據結構的效率不是太高,並發量突然太高,因為這里稍微耗時一些,導致很多線程卡在這里的話是不太好的。所以進行基本的資源隔離和訪問,避免內部復雜的低效率的代碼,導致大量的線程被hang住。
如何修改隔離方案:
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)));
結果cache
Hystrix支持將一個請求結果緩存起來,下一個具有相同key的請求將直接從緩存中取出結果,減少請求開銷。要使用Hystrix cache功能,第一個要求是重寫getCacheKey()
,用來構造cache key;第二個要求是構建context,如果請求B要用到請求A的結果緩存,A和B必須同處一個context。通過HystrixRequestContext.initializeContext()
和context.shutdown()
可以構建一個context,這兩條語句間的所有請求都處於同一個context。
package com.rickiyang.learn.service;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
/**
* cache只有同在一個context中才生效
* 通過HystrixRequestContext.initializeContext()初始化context,通過shutdown()關閉context
*/
public class HystrixCommand4RequestCacheTest extends HystrixCommand<Boolean> {
private final int value;
private final String value1;
protected HystrixCommand4RequestCacheTest(int value, String value1) {
super(HystrixCommandGroupKey.Factory.asKey("RequestCacheCommandGroup"));
this.value = value;
this.value1 = value1;
}
// 返回結果是cache的value
@Override
protected Boolean run() {
return value == 0 || value % 2 == 0;
}
// 構建cache的key
@Override
protected String getCacheKey() {
return String.valueOf(value) + value1;
}
public static void main(String[] args) {
//這里模擬兩個context的情況,在context1中執行的command2b是不能獲取到command2a 中 key 的緩存的
HystrixRequestContext context = HystrixRequestContext.initializeContext();
HystrixCommand4RequestCacheTest command2a = new HystrixCommand4RequestCacheTest(2, "key");
command2a.execute();
command2a.isResponseFromCache();
context.shutdown();
HystrixRequestContext context1 = HystrixRequestContext.initializeContext();
HystrixCommand4RequestCacheTest command2b = new HystrixCommand4RequestCacheTest(2, "key");
command2b.execute();
command2b.isResponseFromCache();
context1.shutdown();
}
}
上面這個例子模擬了兩個context的情況,在context1中執行的command2b是不能獲取到command2a 中 key 的緩存的。
HystrixCommandProperties配置:
/* --------------統計相關------------------*/
// 統計滾動的時間窗口,默認:5000毫秒(取自circuitBreakerSleepWindowInMilliseconds)
private final HystrixProperty metricsRollingStatisticalWindowInMilliseconds;
// 統計窗口的Buckets的數量,默認:10個,每秒一個Buckets統計
private final HystrixProperty metricsRollingStatisticalWindowBuckets; // number of buckets in the statisticalWindow
// 是否開啟監控統計功能,默認:true
private final HystrixProperty metricsRollingPercentileEnabled;
/* --------------熔斷器相關------------------*/
// 熔斷器在整個統計時間內是否開啟的閥值,默認20。也就是在metricsRollingStatisticalWindowInMilliseconds(默認10s)內至少請求20次,熔斷器才發揮起作用
private final HystrixProperty circuitBreakerRequestVolumeThreshold;
// 熔斷時間窗口,默認:5秒.熔斷器中斷請求5秒后會進入半打開狀態,放下一個請求進來重試,如果該請求成功就關閉熔斷器,否則繼續等待一個熔斷時間窗口
private final HystrixProperty circuitBreakerSleepWindowInMilliseconds;
//是否啟用熔斷器,默認true. 啟動
private final HystrixProperty circuitBreakerEnabled;
//默認:50%。當出錯率超過50%后熔斷器啟動
private final HystrixProperty circuitBreakerErrorThresholdPercentage;
//是否強制開啟熔斷器阻斷所有請求,默認:false,不開啟。置為true時,所有請求都將被拒絕,直接到fallback
private final HystrixProperty circuitBreakerForceOpen;
//是否允許熔斷器忽略錯誤,默認false, 不開啟
private final HystrixProperty circuitBreakerForceClosed;
/* --------------信號量相關------------------*/
//使用信號量隔離時,命令調用最大的並發數,默認:10
private final HystrixProperty executionIsolationSemaphoreMaxConcurrentRequests;
//使用信號量隔離時,命令fallback(降級)調用最大的並發數,默認:10
private final HystrixProperty fallbackIsolationSemaphoreMaxConcurrentRequests;
/* --------------其他------------------*/
//使用命令調用隔離方式,默認:采用線程隔離,ExecutionIsolationStrategy.THREAD
private final HystrixProperty executionIsolationStrategy;
//使用線程隔離時,調用超時時間,默認:1秒
private final HystrixProperty executionIsolationThreadTimeoutInMilliseconds;
//線程池的key,用於決定命令在哪個線程池執行
private final HystrixProperty executionIsolationThreadPoolKeyOverride;
//是否開啟fallback降級策略 默認:true
private final HystrixProperty fallbackEnabled;
// 使用線程隔離時,是否對命令執行超時的線程調用中斷(Thread.interrupt())操作.默認:true
private final HystrixProperty executionIsolationThreadInterruptOnTimeout;
// 是否開啟請求日志,默認:true
private final HystrixProperty requestLogEnabled;
//是否開啟請求緩存,默認:true
private final HystrixProperty requestCacheEnabled;