Resilience4j系列 - 使用Resilience4j-circuitbreaker优雅实现服务降级

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。可以针对这个异常进行处理,比如提示“服务暂时不可用”之类的。

猜你喜欢

转载自blog.csdn.net/marlinlm/article/details/122738193