一、断路器介绍
可以看下英文的介绍:https://link.jianshu.com/?t=https%3A%2F%2Fmartinfowler.com%2Fbliki%2FCircuitBreaker.html,主要作用是远程调用的时候能够保护系统,不会让一些宝贵的资源如进程、CPU时间等被耗尽。
二、具体使用
接下来我们看一个具体的实现:https://github.com/resilience4j/resilience4j,看如何使用它来保护系统;
1、引入相关库
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>1.2.0</version>
</dependency>
2、初始化断路器
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
//故障失败率(超过这个阀值才会熔断)
.failureRateThreshold(50f)
//熔断器从打开到半打开的时间(单位:秒)
.waitDurationInOpenState(Duration.ofSeconds(10))
//当断路器关闭时,环形缓冲区的大小(如果环形缓冲区的大小为10,则必须至少请求满10次,才会进行故障率的计算,如果仅仅请求了9次,即使9个请求都失败,熔断器也不会打开)
.slidingWindowSize(50)
//当断路器关闭时,环形缓冲区的大小数量对应的单位(这里是:请求数)
.slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
//half-open时运行通过的请求数,即累计10个请求计算处于half-open状态时的失败率
.permittedNumberOfCallsInHalfOpenState(10)
.build();
CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(config);
circuitBreaker = circuitBreakerRegistry.circuitBreaker("test");
circuitBreaker.getEventPublisher().onStateTransition(event -> {
CircuitBreaker.State fromState = event.getStateTransition().getFromState();
CircuitBreaker.State toState = event.getStateTransition().getToState();
if (fromState.name().equals(CircuitBreaker.State.CLOSED.name())
&& toState.name().equals(CircuitBreaker.State.OPEN.name())) {
}
});
其中CircuitBreakerConfig用来配置断路器,一些参数说明都加上注释了;
还可以通过onStateTransition捕捉相应的事件;
3、具体调用
public class OrderService {
public void saveOrder(String order){
CheckedFunction1<String , String> checkFunction = CircuitBreaker.decorateCheckedFunction(circuitBreaker, this::hello);
String result = null;
try {
//调用保护的方法并获取返回结果信息
result = checkFunction.apply(order);//如果触发熔断,下面代码就不会执行
//备份返回结果数据,如果返回结果数据为null还需删除rocksdb中对应的key
} catch (Throwable throwable) {
if (throwable instanceof CallNotPermittedException) {
//熔断会抛出CallNotPermittedException这个异常
}
}
}
public String hello(String str){
return "hello";
}
}
假设我们要在程序中调用此类OrderService:hello方法,这个方法可能会做一些耗时操作或者说不稳定,先声明一个CheckedFunction1,当然还有CheckedFunction2等等,看你的参数和返回值;
然后调用CheckedFunction1的apply进行计算,这时就会触发上面定义的配置,故障失败率、是否打开等,如果触发了,则会抛出CallNotPermittedException异常,捕捉这个异常就可以处理自己的逻辑了。