Hystrix-短路器原理及實戰
短路器是什麼?顧名思義,短路器的作用是用來阻斷的。即當開啟短路器時,後續對command的執行會直接執行fallback降級。那麼什麼情況下短路器會被開啟呢?下面我們一起了解下這其中的原理。
一、短路器的工作原理
1、短路器開啟的前提是經過短路器的流量超過了一定的閾值。比如說在10s內,經過短路器的流量必須達到20個才會判斷要不要短路。
2、到達短路器的流量異常佔比必須超過一定的閾值。比如我們說在10s,經過短路器的流量達到了30個,同事其中異常的訪問數量,佔到了一定的比例,比如說50%的請求都是異常的,那就開啟短路。
3、短路器達到了一定的閾值,且異常佔比也達到了閾值,那麼此時短路器就會從close狀態轉換到open狀態。
4、短路器開啟的時候,所有經過該短路器的請求全部被短路,不呼叫後端服務,直接fallback降級。
5、經過一段時間之後,短路器會處於半開狀態,讓一條請求經過短路器,看能否正常呼叫,如果呼叫成功,那麼短路器就會自動關閉。
二、短路器相關配置
1、circuitBreaker.enabled:控制短路器是否允許工作,包括跟蹤依賴服務呼叫的健康狀況,以及對異常情況過多時是否允許觸發短路,預設是true。HystrixCommandProperties.Setter().withCircuitBreakerEnabled(boolean value)
2、circuitBreaker.requestVolumeThreshold
3、circuitBreaker.sleepWindowInMilliseconds:設定在短路之後,需要在多長時間內直接reject請求,然後在這段時間之後,再重新到holf-open狀態,嘗試允許請求通過以及自動恢復,預設值是5000毫秒。HystrixCommandProperties.Setter().withCircuitBreakerSleepWindowInMilliseconds(int value)
4、circuitBreaker.errorThresholdPercentage:設定異常請求量的百分比,當異常請求達到這個百分比時,就觸發開啟短路器,預設是50,也就是50%。HystrixCommandProperties.Setter().withCircuitBreakerErrorThresholdPercentage(int value)
5、circuitBreaker.forceOpen:如果設定為true的話,直接強迫開啟短路器,相當於是手動短路了,手動降級,預設false。HystrixCommandProperties.Setter().withCircuitBreakerForceOpen(boolean value)
6、circuitBreaker.forceClosed:如果設定為ture的話,直接強迫關閉短路器,相當於是手動停止短路了,手動升級,預設false。HystrixCommandProperties.Setter().withCircuitBreakerForceClosed(boolean value)
三、實戰
3.1、建立command
public class CommandCircuitBreaker extends HystrixCommand<String> {
private String tag;
public CommandCircuitBreaker(String tag) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("CommandCircuitBreakerGroupKey"))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()//
.withCircuitBreakerRequestVolumeThreshold(30)// 設定短路器的流量必須到達30
.withCircuitBreakerErrorThresholdPercentage(40)// 異常佔比達到40%
.withCircuitBreakerSleepWindowInMilliseconds(3000)));// 滑動視窗3s,3s後處於半開狀態
this.tag = tag;
}
@Override
protected String run() throws Exception {
if ("error".equals(tag)) {
throw new Exception("丟擲異常");
}
return "-----------------成功-----------------";
}
@Override
protected String getFallback() {
return "-----------------降級處理-----------------";
}
}
3.2、執行command
public class CommandCircuitBreakerTest {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 15; i++) {
CommandCircuitBreaker breaker = new CommandCircuitBreaker("success");
System.out.println("第" + (i + 1) + "次請求,結果為:" + breaker.execute());
}
for (int i = 0; i < 25; i++) {
CommandCircuitBreaker breaker = new CommandCircuitBreaker("error");
System.out.println("第" + (i + 1) + "次請求,結果為:" + breaker.execute());
}
// 因為時間視窗統計異常佔比需要時間,所以這裡等待了2s後
Thread.sleep(2000);
for (int i = 0; i < 10; i++) {
CommandCircuitBreaker breaker = new CommandCircuitBreaker("success");
System.out.println("第" + (i + 1) + "次請求,結果為:" + breaker.execute());
}
// 統計單位,有一個時間視窗的,我們必須要等到那個時間視窗過了以後,才會說,hystrix看一下最近的這個時間視窗
// 比如說,最近的10秒內,有多少條資料,其中異常的資料有沒有到一定的比例
// 如果到了一定的比例,那麼才會去短路
System.out.println("嘗試等待3秒鐘。。。。。。");
Thread.sleep(3000);
for (int i = 0; i < 10; i++) {
CommandCircuitBreaker breaker = new CommandCircuitBreaker("success");
System.out.println("第" + (i + 1) + "次請求,結果為:" + breaker.execute());
}
}
}
3.3、執行結果
(1)成功執行15次之後,開始丟擲異常
(2)後面25次都是異常請求,然後等待2s,讓短路器進行異常佔比統計。再發起正常的請求,此時直接走了fallback降級處理,我們再等待3s,讓短路器處於半開狀態,發起正常請求,此時執行成功。