熔断器默认值是什么、为什么我的服务连续失败也没熔断?默认只等 1 秒的超时从哪来?按 id 怎么配?业务异常会不会触发熔断?id 用用户 ID 会怎样?这篇在 Spring Cloud CircuitBreaker 5.0.3 与 Resilience4j 2.3.0 上用真实的调用逐项测。
id=a:滑动窗口 COUNT_BASED 100,最少调用数 100,失败率阈值 50.0%,打开状态等待 60 秒,半开允许调用数 10;超时 1000 ms
连续 30 次抛 IllegalStateException 的调用:{fallback:IllegalStateException=30},supplier 真正被调用 30 次,总耗时 2 ms,状态 CLOSED
之后状态:CLOSED(窗口内调用 31,失败 30,被拒绝 0)
一次睡 1.5 秒的调用:{fallback:TimeoutException=1},supplier 真正被调用 1 次,总耗时 1004 ms,状态 CLOSED窗口 100、最少 100 次调用、失败率 50%、打开等待 60 秒、超时 1 秒。
id=orders:滑动窗口 COUNT_BASED 10,最少调用数 5,失败率阈值 50.0%,打开状态等待 2 秒,半开允许调用数 10;超时 3000 ms id=strict:滑动窗口 COUNT_BASED 4,最少调用数 2,失败率阈值 50.0%,打开状态等待 60 秒,半开允许调用数 10;超时 300 ms 先在注册表里「偷看」id=peeked(没有经过 factory.run):先直接问注册表 CircuitBreakerRegistry 要 peeked:id=peeked:滑动窗口 COUNT_BASED 100,最少调用数 100,失败率阈值 50.0%,打开状态等待 60 秒,半开允许调用数 10;超时 1000 ms 然后再通过 factory 调用并读取配置:id=peeked:滑动窗口 COUNT_BASED 100,最少调用数 100,失败率阈值 50.0%,打开状态等待 60 秒,半开允许调用数 10;超时 1000 ms
configureDefault 与按 id 的 configure;先问注册表会让配置失效。
orders 连续 5 次失败:{fallback:IllegalStateException=4, fallback:CallNotPermittedException=1},supplier 真正被调用 4 次,总耗时 2 ms,状态 OPEN
状态:OPEN(窗口内调用 5,失败 4,被拒绝 1)
再调用 3 次(正常的 supplier):{fallback:CallNotPermittedException=3},supplier 真正被调用 0 次,总耗时 0 ms,状态 OPEN
等 2.2 秒后调用 1 次:{ok=1},supplier 真正被调用 1 次,总耗时 2 ms,状态 HALF_OPEN
状态:HALF_OPEN(窗口内调用 1,失败 0,被拒绝 0)
再连续调用 9 次正常的 supplier:{ok=9},supplier 真正被调用 9 次,总耗时 1 ms,状态 CLOSED
状态:CLOSED(窗口内调用 5,失败 0,被拒绝 0)
strict(超时 300 ms)一次睡 1.5 秒的调用:{fallback:TimeoutException=1},supplier 真正被调用 1 次,总耗时 305 ms,状态 OPEN
另一个 id=bad 连续 5 次抛 IllegalArgumentException(调用方传错参数这类业务异常):{fallback:IllegalArgumentException=5},supplier 真正被调用 5 次,总耗时 0 ms,状态 OPEN
同一个 id 不同调用点共用一个熔断器:orders 已 OPEN 过之后 id=orders2 的状态 CLOSED(窗口内调用 0,失败 0,被拒绝 0)OPEN 不调 supplier,等待后半开,凑满允许数后关闭;业务异常也算失败。
配了 configs.default(窗口 7、最少 3 次)与 instances.byprop(窗口 3、最少 2 次)、timelimiter.configs.default.timeout-duration=2s:
id=byprop:滑动窗口 COUNT_BASED 3,最少调用数 2,失败率阈值 50.0%,打开状态等待 60 秒,半开允许调用数 10;超时 2000 ms
id=other:滑动窗口 COUNT_BASED 7,最少调用数 3,失败率阈值 50.0%,打开状态等待 60 秒,半开允许调用数 10;超时 2000 ms
用 user-0 … user-999 一千个不同的 id 各调用一次:注册表里的熔断器个数 = 1000resilience4j.* 属性有效;id 不要带用户或请求参数。