暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Spring断路器使用

程序员升级之路 2021-09-12
418

一、断路器介绍

可以看下英文的介绍: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异常,捕捉这个异常就可以处理自己的逻辑了。



        多机房RPC调用实践

        聊聊DDD的分层架构

        MyBatis源码分析三:Sql执行

        文章转载自程序员升级之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论