熔断器三种状态详解:关闭、打开与半开
熔断器(Circuit Breaker)是微服务架构中实现弹性容错的核心模式。它通过三种状态——关闭(Closed)、打开(Open)和半开(Half-Open)——的自动转换,保护下游服务不被级联故障压垮。理解这三种状态的定义及其转换条件,是正确配置熔断器参数的前提。
3.1 状态定义与核心特征
下表从请求处理方式、健康指标和典型行为三个维度,对比三种状态的本质差异:
| 状态 | 请求处理方式 | 健康指标 | 典型行为 |
|---|---|---|---|
| 关闭(Closed) | 正常转发请求到下游服务 | 统计失败率/超时率 | 持续监控,未达阈值 |
| 打开(Open) | 直接拒绝请求(快速失败) | 记录拒绝次数与等待时间 | 返回降级响应,不调用下游 |
| 半开(Half-Open) | 允许有限数量的探测请求通过 | 评估探测请求的成功率 | 试探下游是否恢复 |
3.2 关闭状态(Closed)—— 正常运行的基线
定义:熔断器的初始状态,也是服务健康时的常态。在此状态下,所有请求都会正常转发给下游服务,熔断器内部维护一个滑动窗口计数器,持续记录请求的成功/失败情况。
转换条件:
- 保持关闭:当失败率低于预设阈值(例如 50%)时,熔断器维持在关闭状态。
- 触发打开:当滑动窗口内的失败率 达到或超过阈值,且请求量达到最小请求数(例如 10 次),熔断器立即从 Closed → Open。
关键参数:关闭状态主要受
failureRateThreshold(失败率阈值)和 slidingWindowSize(滑动窗口大小)控制。窗口大小决定了统计的灵敏度,窗口越小,对瞬时故障越敏感。
3.3 打开状态(Open)—— 快速失败的保护期
定义:熔断器触发后的保护状态。在此状态下,所有对下游的调用请求都会被立即拒绝,直接返回降级响应(如缓存数据、默认值或错误提示),避免下游服务因持续等待而耗尽资源。
转换条件:
- 保持打开:熔断器内部维护一个计时器,在
waitDurationInOpenState(例如 30 秒)内,始终处于打开状态。 - 进入半开:当等待时间 耗尽,熔断器自动从 Open → Half-Open,允许少量探测请求试探下游。
避坑提示:打开状态的持续时间不宜过短(< 5 秒),否则下游服务尚未恢复就再次涌入大量请求,导致“熔断抖动”;也不宜过长(> 120 秒),否则会过度降低系统可用性。建议根据下游服务的平均恢复时间(MTTR)来设定。
3.4 半开状态(Half-Open)—— 恢复试探的桥梁
定义:熔断器从打开状态恢复前的过渡状态。在此状态下,熔断器会允许有限数量的探测请求(例如 3 个)通过,去真实调用下游服务,并根据这些请求的结果决定下一步动作。
转换条件:
- 恢复关闭:如果所有探测请求都成功(或成功率达标),熔断器认为下游已恢复,从 Half-Open → Closed,重置计数器,恢复正常流量。
- 回到打开:如果任意一个探测请求失败(或超时),熔断器认为下游仍未恢复,立即从 Half-Open → Open,并重新开始等待计时。
核心参数:半开状态由
permittedNumberOfCallsInHalfOpenState(半开状态允许的调用次数)控制。该值不宜过大,否则可能在下游脆弱时造成二次冲击;也不宜过小(如 1 次),否则单次失败会导致误判。
3.5 状态转换流程图
下图完整展示了熔断器三种状态之间的转换路径与触发条件:
3.6 状态转换的时序与参数映射
为了更直观地理解参数如何影响状态转换,下面以 Resilience4j 的默认配置为例,展示一个完整的熔断周期:
// Resilience4j 熔断器配置示例(Java)
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 关闭状态:失败率阈值 50%
.slidingWindowSize(10) // 关闭状态:滑动窗口大小 10 次
.minimumNumberOfCalls(5) // 关闭状态:最小请求数 5 次
.waitDurationInOpenState(Duration.ofSeconds(30)) // 打开状态:等待 30 秒
.permittedNumberOfCallsInHalfOpenState(3) // 半开状态:允许 3 次探测
.build();
转换时序示例:
- 关闭状态:最近 10 次请求中有 6 次失败(失败率 60% > 50%),且总请求数 ≥ 5 → 触发打开。
- 打开状态:所有请求立即降级,持续 30 秒。30 秒后自动进入半开。
- 半开状态:允许 3 个探测请求通过。如果 3 次全部成功 → 恢复关闭;如果任意 1 次失败 → 回到打开,重新计时 30 秒。
3.7 三种状态的核心差异总结
| 对比维度 | 关闭状态 | 打开状态 | 半开状态 |
|---|---|---|---|
| 流量通过 | 全部通过 | 全部拒绝 | 仅限探测请求 |
| 下游压力 | 正常压力 | 零压力 | 极小压力 |
| 响应延迟 | 正常延迟 | 即时降级(毫秒级) | 探测请求正常延迟 |
| 主要参数 | failureRateThresholdslidingWindowSize |
waitDurationInOpenState |
permittedNumberOfCallsInHalfOpenState |
| 典型场景 | 服务健康运行 | 下游故障或超载 | 下游恢复试探期 |
实践要点:半开状态是熔断器设计的精髓——它避免了“熔断后永久关闭”或“恢复后立即全量流量”两个极端。通过合理配置
permittedNumberOfCallsInHalfOpenState 和 waitDurationInOpenState,可以在保护下游和快速恢复之间取得平衡。