Resilience4j.md 6.4 KB


title: Resilience4j熔断器Circuit Breaker date: 2023-05-31

tags: Java

介绍

从这一篇起我们将来讲述 Resilience4j熔断器的使用spring中如何使用以及背后的原理(当然要结合源码来探讨)。

Resilience4j配置

任何组件都会有配置 可以说配置是一个组件的基础 无法绕过它。例如我们前面说的Archaius作为NetflixOss的配置基础 Hystrix 、Ribbon都是在其基础上进行扩展的 ,可以说它在整个NetflixOss中扮演者重要的角色。 而今天我们的主角的配置功能不像Archaius那么复杂 需要专门拿专栏来讲述。

创建配置实例


 CircuitBreakerConfig.ofDefaults();

 CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
            .slidingWindowSize(10)
          .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
            .build();
            

各个配置项含义


   CircuitBreakerConfig.custom()
            .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
            .slidingWindowSize(10)
            .automaticTransitionFromOpenToHalfOpenEnabled(true)
            .currentTimestampFunction( clock -> clock.millis() , TimeUnit.MILLISECONDS)
            .failureRateThreshold(0.1f)
            .ignoreException(throwable -> {
              if (throwable instanceof  NullPointerException){
                return false;
              }
              return true;
            })
            .maxWaitDurationInHalfOpenState(Duration.ofSeconds(60))
            .minimumNumberOfCalls(1)
            .slowCallDurationThreshold(Duration.ofSeconds(60))
            .slowCallRateThreshold(0.1f)
            .waitDurationInOpenState(Duration.ofMinutes(1)).build();
            
  • slidingWindowType: 滑动窗口类型。还记得上一篇我们介绍过 Resilience4J可以在基于计数的滑动窗口和基于时间的滑动窗口之间进行选择。
  • waitDurationInOpenState: 将间隔功能配置为具有固定的等待时间,该间隔时间控制CircuitBreaker保持打开状态多长时间,然后再切换到半打开状态。 默认值为60秒
  • automaticTransitionFromOpenToHalfOpenEnabled : 一旦waitDurationInOpenState通过,启用从OPEN到HALF_OPEN状态的自动转换
  • currentTimestampFunction : 该函数返回CircuitBreaker的当前时间戳。默认实现使用System.nanoTime()来计算当前时间戳。当然我们可以通过设置该函数来实现毫秒值
  • slidingWindowSize: 滑动窗口的大小 如果窗口类型是基于计数的滑动窗口 那么该值得含义就是固定数组的大小存放每次请求的结果。如果窗口类型是 基于时间的滑动窗口 那么该值得含义就是窗口大小 例如10 就会有10个存储桶每个存储桶窗口大小是1s
  • failureRateThreshold : 以百分比配置故障率阈值。如果故障率等于或大于阈值,则CircuitBreaker转换为打开状态并开始短路呼叫。 阈值必须大于0且不大于100。默认值为50。
  • ignoreException : 配置是否需要忽略的异常,如果有需要忽略的异常不计入失败 可以通过这个配置项来配置
  • minimumNumberOfCalls : 在CircuitBreaker可以计算错误率之前,配置所需的最小呼叫数(每个滑动窗口时段)。例如,如果值为10,那么在可以计算失败率之前,必须至少记录10个呼叫。如果仅记录了9个呼叫,则即使所有9个呼叫均失败,CircuitBreaker也不会转换为打开。默认为100。
  • maxWaitDurationInHalfOpenState : 使用固定的等待时间配置CircuitBreaker,该持续时间控制CircuitBreaker在切换为打开之前应保持半开状态的时间。这是一个可选参数。默认情况下,CircuitBreaker将保持半开状态,直到 minimumNumberOfCalls成功或失败为止。
  • slowCallDurationThreshold: 慢执行的时间阈值,如果大于该值的执行被认为是慢执行 会被统计。如果当慢执行的比例超过一定比例的时候就会被熔断。 默认值60s
  • slowCallRateThreshold : 上面说过 如果当慢执行的比例超过一定比例的时候就会被熔断 那这个值就是配置慢执行的比例的。 默认为100。 也就意味着所有的请求都比slowCallDurationThreshold慢 才会被熔断。
  • waitIntervalFunctionInOpenState: 配置间隔功能,该功能控制CircuitBreaker在打开到半开状态之前应保持打开状态多长时间。默认的时间间隔函数返回固定的60秒等待时间。如果需要指数退避算法,则自定义间隔函数很有用。
  • recordException: 是否应将异常记录为失败,从而提高失败率。如果异常应该算作失败,则谓词必须返回true。如果异常应将视为成功,则谓词必须返回false,除非ignoreExceptions明确忽略了该异常。
  • writableStackTraceEnabled : 启用可写的堆栈跟踪。设置为false时, Exception#getStackTrace返回长度为零的数组。当断路器打开时,这可以用来减少垃圾日志,因为已知异常的原因。

配置如何用

上面说了那么多的配置 那么这些配置到底是怎么使用的。我们通过一个demo先展示一下。


 	given(helloWorldService.returnHelloWorld()).willReturn("hello word");

    CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()

            .slidingWindowSize(10)

          .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED)
            .build();

    CircuitBreaker circuitBreaker = CircuitBreaker.of("test", circuitBreakerConfig);
    Supplier<String> stringSupplier = circuitBreaker.decorateSupplier(helloWorldService::returnHelloWorld);
    assertThat(stringSupplier.get()).isEqualTo("hello word");
    

结语

断路器的配置到这就结束了。上面一坨的配置后面用到的时候再回头来查就可以了,无需死记。Resilience4j属于轻量级的框架 本身并没有依赖专门的配置工具,自己实现的配置也是相当的简单。值得注意的是Resilience4j每一个模块都会有自己的配置 这些配置是相互独立的。例如:重试功能的配置 RateLimiterConfig 、限流模块的配置 RateLimiterConfig 等等。这些我们后面遇到的时候就不再花时间介绍了。相对于熔断的配置 其他模块的配置还算简单。