Maven集成
<!-- resilience4j -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.7.0</version>
</dependency>
<!-- resilience spring boot integration with annotation requires spring aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
通过注解@CircuitBreaker实现
在配置文件里增加circuitbreaker配置信息:
resilience4j:
circuitbreaker:
configs:
default:
ringBufferSizeInClosedState: 1 # 熔断器关闭时的缓冲区大小
ringBufferSizeInHalfOpenState: 1 # 熔断器半开时的缓冲区大小
waitDurationInOpenState: 60000 # 熔断器从打开到半开需要的时间
failureRateThreshold: 100 # 熔断器打开的失败阈值
eventConsumerBufferSize: 5 # 事件缓冲区大小
registerHealthIndicator: true # 健康监测
automaticTransitionFromOpenToHalfOpenEnabled: true # 是否自动从打开到半开,不需要触发
instances:
backendA:
baseConfig: default
waitDurationInOpenState: 60000
failureRateThreshold: 100
为需要实现服务降级的方法增加@CircuitBreaker注解
@Component
public class CircuitBreakCheckedService {
@CircuitBreaker(name="backendA", fallbackMethod="fallback")
public boolean checkedMethod(int someInput){
//写一些会抛出异常的代码。
return true;
}
//该方法的返回类型必须和注解的方法的返回类型一样。
//该方法的名字必须和fallbackMethod的值一样。
public boolean fallback(Throwable t){
return false;
}
//如果抛出的异常时CallNotPermittedException。那么这个方法会被执行。
public boolean fallback(CallNotPermittedException t){
return false;
}
//fallback方法也可以带和注解方法一样的入参。
public boolean fallback(int someInput, Throwable t){
return false;
}
}
通过编程方式实现
//1.创建circuitbreaker配置
CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
.failureRateThreshold(100) //窗口中触发断路器的失败率
.waitDurationInOpenState(Duration.ofMillis(60000)) //从断开到半开的时间
.ringBufferSizeInClosedState(3) //断路器未断开时,统计样本的窗口大小
.permittedNumberOfCallsInHalfOpenState(2) //断路器半开时,允许通过的请求数量
.automaticTransitionFromOpenToHalfOpenEnabled(true) //是否自动将断路器从断开切换到半开状态
.build();
//2.创建CircuitBreaker对象
CircuitBreaker circuitBreaker = CircuitBreaker.of("myCircuitBreaker", circuitBreakerConfig);
//3.利用circuitBreaker包装需要进行服务熔断的代码
CheckedFunction0<Boolean> function = CircuitBreaker.decorateCheckedSupplier(
circuitBreaker, () -> {
//...
//把需要控制的方法写在这里。
//这是一些会抛出异常的代码。
//...
});
//4.使用Try来执行该包装后的方法。
Try
.of(f)
.recover(throwable -> {
//被控制的方法抛出任何异常之后的处理逻辑
})
.recover(CallNotPermittedException.class, e -> {
//这是特别针对某个特定异常的处理逻辑,只有最精确匹配的异常处理逻辑会被执行
})
.get();
如果断路器断开了,那么每次运行时都会触发CallNotPermittedException。可以针对这个异常进行处理,比如提示“服务暂时不可用”之类的。