现场是这样的。演练把下游错误率打到 20%,熔断器一直保持关闭,请求全部慢重试,线程池被占满,本地错误率反而升到 40%,配置里的阈值是 50%。

中间走过弯路,把「慢请求没被计入失败,只有 5xx 才算」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。触发阈值高于演练注入的故障幅度;统计窗口过长,20% 被历史成功稀释;半开探测过于频繁,一直误判下游健康。

上来先看熔断器的实时指标

curl -s http://api:8080/actuator/circuitbreakers | jq '.circuitBreakers[] | {name:.name, state:.state}'

然后把阈值调到 20% 并缩短窗口

resilience4j.circuitbreaker.instances.pay.failure-rate-threshold=20

接着把慢调用也算成失败

resilience4j.circuitbreaker.instances.pay.slow-call-duration-threshold=800ms

剩下的就是重演确认能进入 open 状态

python chaos.py --target pay --error-rate 0.2 --duration 2m && curl -s http://api:8080/actuator/circuitbreakers | jq '.circuitBreakers[].state'

怎么算真的好了,看的是同一批现象。演练开始两分钟内熔断器进入 open,线程池占用回落,本地错误率不再继续上升,恢复后自动半开。

熔断阈值要比可接受的错误率高一点但不能高太多,慢调用不计入失败是最常见的配置漏洞。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189