Hystrix是一個延遲和容錯庫,旨在隔離對遠程系統,服務和第三方庫的訪問點,停止級聯故障,並在複雜的分佈式系統中實現彈性,在這些系統中,故障是不可避免的。
依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
SpringBootApplication入口中需要添加@EnableCircuitBreaker
註解,此時Spring工廠會啓動AOP方式對所有的方法上有@HystrixCommand
的業務方法添加熔斷策略。
@SpringBootApplication
@EnableCircuitBreaker
public class HystrixSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixSpringBootApplication.class,args);
}
}
在業務方法上添加@HystrixCommand
註解實現熔斷。
@HystrixCommand
@Override
public User queryUserById(Integer id) {
System.out.println(Thread.currentThread().getId());
return new User("未熔斷", new Date(), true, 11.11);
}
線程隔離
默認該方法的執行會啓動新的線程執行和主程序不在一個線程中,因此如果上下文中存在ThreadLocal變量,在該方法中就失效了。因此一般可以通過設置commandProperties註解屬性,設置線程就可以了。
- 默認情況Service和Controller線程ID
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE")
})
@Override
public User queryUserById(Integer id) {
System.out.println("Service線程ID:" + Thread.currentThread().getId());
return new User("未熔斷", new Date(), true, 11.11);
}
- 設置後Service和Controller線程ID
execution.isolation.strategy
該屬性的可選值有兩個THREAD
和SEMAPHORE
默認值是THREAD
。①一般如果一個實例一秒鐘有100個併發,此時因爲頻繁啓動線程的開銷過大此時一般考慮使用SEMAPHORE,②非網絡調用。
Fallback
過在@HystrixCommand中聲明fallbackMethod
的名稱可以實現優雅降級,如下所示:
@HystrixCommand(fallbackMethod = "fallbackMethodQueryUserById")
@Override
public User queryUserById(Integer id) {
System.out.println(Thread.currentThread().getId());
int i=10/0;
return new User("未熔斷", new Date(), true, 11.11);
}
public User fallbackMethodQueryUserById(Integer id, Throwable e) {
System.out.println(e.getMessage());
return new User("熔斷降級後", new Date(), true, 11.11);
}
調用結果:
注意要求fallbackMethod方法和目標方法必須在同一個類中,具有相同的參數(異常參數可選)
Error Propagation
根據此描述,@ HystrixCommand
能夠指定應忽略的異常類型。如下所述ArithmeticException: / by zero
將不會觸發fallbackMethod方法。
// @HystrixCommand(fallbackMethod = "fallbackMethodQueryUserById")
// @HystrixCommand(commandProperties = {
// @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE")
// })
@HystrixCommand(fallbackMethod = "fallbackMethodQueryUserById",ignoreExceptions = {ArithmeticException.class})
@Override
public User getUser(Integer id) {
System.out.println("Service線程ID:" + Thread.currentThread().getId());
int i = 10 / 0;
return new User("未熔斷", new Date(), true, 11.11);
}
public User fallbackMethodQueryUserById(Integer id, Throwable e) {
System.out.println(e.getMessage());
return new User("熔斷降級後", new Date(), true, 11.11);
}
請求超時熔斷
用戶可以通過設置execution.isolation.thread.timeoutInMilliseconds
屬性設置一個方法最大請求延遲,系統會拋出HystrixTimeoutException
@HystrixCommand(fallbackMethod = "fallbackMethodQueryUserById",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="100")
})
@Override
public User getUser(Integer id) {
System.out.println("Service線程ID:" + Thread.currentThread().getId());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// int i = 10 / 0;
return new User("未熔斷", new Date(), true, 11.11);
}
public User fallbackMethodQueryUserById(Integer id, Throwable e) {
System.out.println(e.getMessage());
return new User("超時熔斷", new Date(), true, 11.11);
}
執行結果:
https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica
https://github.com/Netflix/Hystrix/wiki/Configuration
Hystrix Dashboard
依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
SpringBoot入口類添加
@EnableHystrixDashboard
註解
訪問頁面http://localhost:端口/hystrix