每日一句
成功之前我们要做应该做得事情,成功之后才可以做喜欢的事情
介绍
从这一篇起我们将来讲述 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)
//滑动窗口类型 COUNT_BASED基于计数的滑动窗口
.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 等等。这些我们后面遇到的时候就不再花时间介绍了。相对于熔断的配置 其他模块的配置还算简单。