使用Resilience4j CircuitBreaker实现服务调用熔断
断路器CircitBreaker
是 Resilience4j 的核心机制,通过有限状态机和环形位缓冲区(Ring Bit Buffer) 实现故障检测与熔断
CircitBreaker
采用装饰器模式对原有请求进行装饰,同时会增加方法执行时间的计算,方法执行结束后发生状态的流转。
一、基础概念
滑动窗口
滑动窗口可以类比为一个环形的圆圈,这个圆圈存储的元素上限就是slidingWindowSize
。对于时间计数而言,这个圆圈代表的就是slidingWindowSize
秒内接受处理的请求,对这些请求进行聚合计算,超过滑动窗口的调用会被丢弃;对于次数计数而言,这个圆圈代表的就是最近slidingWindowSize
次调用,对最近的这些请求进行聚合计算。
状态流转
Resilience4j
支持的状态包含三个普通状态:CLOSED
、OPEN
和HALF_OPEN
以及三个特殊状态:METRICS_ONLY
、DISABLED
和FORCED_OPEN
;熔断主要使用前三个状态。
CLOSED --> OPEN
状态变更:
前提:调用次数需要达到最小调用次数minimumNumberOfCalls
要求
- 失败调用(默认所有异常都算作失败)比例超过阈值
ailureRateThreshold
- 慢调用比例超过阈值
slowCallRateThreshold
OPEN --> HALF_OPEN
状态变更:
状态处于OPEN
时,所有的请求会字节被熔断并抛出 CallNotPermittedException
异常。
前提:等待时间已经达到OPEN
状态最大等待时间waitDurationInOpenState
,熔断器尝试开始接受请求
- 启用自动状态转换配置
automaticTransitionFromOpenToHalfOpenEnabled
,会由监控线程将状态变更为HALF_OPEN
接受请求 - 超过最大等待时间后,在尝试获取凭证时,会将状态变更为
HALF_OPEN
HALF_OPEN --> OPEN
状态变更:
- 允许执行请求的授权凭证
permittedNumberOfCallsInHalfOpenState
聚合计算后,失败比例或者慢调用还是超过阈值 - 设置
HALF_OPEN
状态最大等待时间maxWaitDurationInHalfOpenState
非0时,超过等待时间,请请求记录无法计算阈值比较时,会将状态变更为OPEN
HALF_OPEN --> CLOSED
状态变更:
- 失败比例和慢调用比例低于失败阈值和慢调用阈值
二、配置属性
1、滑动窗口定义
配置属性 | 默认值 | 描述 |
---|---|---|
slidingWindowType |
count_based |
滑动窗口类型,支持count_based 和time_based ,如果类型为count_based ,最近的slidingWindowSize 会记录和聚合,如果类型为time_based ,最近的slidingWindowSize 秒的请求会记录和聚合 |
slidingWindowSize |
100 | 滑动窗口的大小,当状态为CLOSED 时记录请求结果 |
minimumNumberOfCalls |
100 | 每个窗口周期最小调用次数,达到最小调用次数时才会用于失败率和慢调用。例如,配置值为10时,调用次数必须到达10次,才会进行结果计算,如果在窗口周期内只调用了9次,即使全部失败也不会触发熔断器计算 |
2、失败、超时阈值
配置属性 | 默认值 | 描述 |
---|---|---|
failureRateThreshold |
50 | 失败阈值,百分比;如果失败比例大于等与阈值时,状态由CLOSED 变为OPEN |
slowCallRateThreshold |
100 | 慢调用阈值,百分比;如果调用执行事件大于 slowCallDurationThreshold 时认为是慢调用 |
slowCallDurationThreshold |
60s | 慢调用阈值,超过当前值考虑为慢调用 |
3、状态轮转
配置属性 | 默认值 | 描述 |
---|---|---|
permittedNumberOfCallsInHalfOpenState |
10 | 状态为HALF_OPEN 时允许通过的调用凭证数 |
maxWaitDurationInHalfOpenState |
0[ms] | HALF_OPEN 状态保持的最大时间,超过该时间状态会变为OPEN ;如果配置为0时会等待所有的凭证完成请求 |
automaticTransitionFromOpenToHalfOpenEnabled |
false |
true :状态会自动由OPEN 变为HALF_OPEN ,不需要由请求触发,同时会创建一个线程监控实例是否已经达到waitDurationInOpenState 时间false :状态不会自动发生转换,需要有请求发生触发状态变更为HALF_OPEN ,同时也不会启动一个监控线程检查 |
waitDurationInOpenState |
60s | OPEN 状态时,状态变为HALF_OPEN 的最大等待时间,启用状态自动变化时才生效 |
enableExponentialBackoff |
采用指数增长计算OPEN 状态等待时间wait_time = initial_interval * (multiplier ^ (retry_attempt - 1)) |
|
exponentialBackoffMultiplier |
指数增长因子 | |
exponentialMaxWaitDurationInOpenState |
指数增长方式允许的最大值 | |
enableRandomizedWait |
是否采用随即时间等待,随机值:当前值 * 随机因子 | |
randomizedWaitFactor |
随机因子 |
4、失败异常
配置属性 | 默认值 | 描述 |
---|---|---|
recordExceptions |
null 默认记录所有异常 |
需要作为失败记录的异常列表,和列表匹配或者时继承列表中的异常都会算作失败;如果指定了异常列表,默认其他异常都作为成功,除非明确在ignoreException 列出 |
ignoreExceptions |
null |
一个异常列表,即不作为成功也不作为失败,不会导致成功和失败数目增加 |
recordFailurePredicate |
throwable -> true 默认记录所有异常 |
一个自定义的Predicate ,用于判断异常是否作为失败异常记录 |
ignoreExceptionPredicate |
throwable -> false |
一个自定义的Predicate ,用于判断异常是否需要被忽略 |
writableStackTraceEnabled |
true |
是否打印详细日志堆栈,此配置只针对断路器处于OPEN 状态时熔断请求时抛出异常CallNotPermittedException |
5、检测指标
resilience4j.circuitbreaker.metrics.enabled = true
resilience4j.circuitbreaker.configs.defaults.register-health-indicator = true
management.health.circuitbreakers.enabled = true
三、使用示例
1、基础置
1.1 pom
依赖
1 |
|
1.2 yaml配置
resilience4j.circuitbreaker.configs
:定义CircuitBreaker
配置信息resilience4j.circuitbreaker.instances
:定义CircuitBreaker
实例信息resilience4j.circuitbreaker.metrics
:定义CircuitBreaker
指标信息
1 |
|
2、使用注解
2.1 使用固定名称并指定fallback
1 |
|
2.2 使用方法名作为CircuitBreaker名称
1 |
|
2.3 使用Spel表达时动态获取参数作为CircuitBreaker名称
1 |
|
3、代码自定义装饰
1 |
|
四、附录
https://github.com/resilience4j/resilience4j-spring-boot3-demo/tree/master
使用Resilience4j CircuitBreaker实现服务调用熔断
https://probiecoder.cn/resilience4j/circuitbreaker.html