3. 熔断器模式基础:三种状态与核心参数
熔断器(Circuit Breaker)是分布式系统中防止级联故障的关键模式。它通过监控对下游服务的调用失败率,在系统不稳定时主动切断流量,为上游提供快速失败(Fail Fast)而非长时间阻塞的体验。熔断器的行为由有限状态机驱动,包含三个核心状态和一组可调参数。
3.1 熔断器三种状态与转换逻辑
熔断器在运行过程中会在 Closed(关闭)、Open(打开)、Half-Open(半开) 三种状态间循环转换。每个状态对应不同的流量处理策略:
| 状态 | 含义 | 流量处理方式 | 触发条件 |
|---|---|---|---|
| Closed | 熔断器关闭,系统正常运行 | 请求正常通过,计数器累积失败次数 | 初始状态;失败率低于阈值时保持 |
| Open | 熔断器打开,拒绝请求 | 请求直接返回失败(快速失败),不调用下游 | 失败率超过阈值时进入 |
| Half-Open | 熔断器半开,试探性放行 | 允许少量请求通过,探测下游是否恢复 | Open 状态超时后自动进入 |
关键原则:熔断器只在 Closed 状态下真正调用下游服务;Open 状态直接短路;Half-Open 状态用于恢复探测,避免服务刚恢复就被流量冲垮。
3.2 状态转换逻辑详解
状态转换由两个核心事件驱动:失败率阈值触发和超时计时器到期。下图展示了完整的状态机流转路径:
转换要点:从 Open 到 Half-Open 的转换是自动的,由超时计时器控制;从 Half-Open 到 Closed 或 Open 的转换取决于探测请求的成功率。通常 Half-Open 状态下只放行 1~3 个请求,若全部成功则关闭熔断器,否则立即重新打开。
3.3 核心参数详解
熔断器的行为由三个核心参数控制:失败率阈值、滑动窗口大小和超时时间。合理配置这些参数是熔断器生效的前提。
| 参数 | 典型值 | 作用 | 配置建议 |
|---|---|---|---|
| 失败率阈值 | 50%~80% | 触发熔断的失败比例下限 | 根据服务 SLA 调整;核心服务建议 50%,非核心可放宽至 80% |
| 滑动窗口大小 | 10~100 次请求 | 统计失败率的请求样本数量 | 高 QPS 服务用较大窗口(100),低 QPS 服务用较小窗口(10) |
| 超时时间 | 5~60 秒 | 熔断器从 Open 到 Half-Open 的等待时长 | 根据下游恢复时间设定;短超时(5s)适合快速恢复的服务,长超时(60s)适合需要人工介入的场景 |
3.4 参数联动与配置示例
三个参数并非独立工作,它们共同决定了熔断器的灵敏度和恢复速度。以下是一个典型的配置示例:
# 熔断器配置示例(以 Resilience4j 为例)
circuit-breaker:
name: user-service-cb
sliding-window-size: 20 # 滑动窗口统计最近 20 次请求
failure-rate-threshold: 60 # 失败率超过 60% 触发熔断
wait-duration-in-open-state: 15s # Open 状态持续 15 秒后进入 Half-Open
permitted-number-of-calls-in-half-open-state: 3 # Half-Open 允许 3 个探测请求
record-exceptions:
- java.io.IOException
- java.util.concurrent.TimeoutException
常见误区:不要将超时时间设置得过短(如 1 秒),否则熔断器会在下游尚未恢复时频繁进入 Half-Open 状态,导致“抖动”;也不要将失败率阈值设置得过低(如 10%),否则短暂的网络波动就会触发熔断,影响正常流量。
3.5 状态转换与错误预算的关联
熔断器的状态转换与错误预算(Error Budget)存在天然联动:
- Closed 状态:消耗错误预算,每次失败都计入预算消耗。
- Open 状态:停止消耗错误预算(请求被快速拒绝,不计入失败),为系统争取恢复时间。
- Half-Open 状态:试探性消耗错误预算,若探测成功则恢复预算消耗节奏;若失败则继续冻结预算。
这种联动机制使得熔断器成为错误预算的“阀门”——在预算充足时允许流量通过,在预算紧张时自动切断流量,防止预算被快速耗尽。
实践要点:在实现熔断器与错误预算联动时,建议将熔断器的失败率阈值设置为错误预算消耗率的 1.5~2 倍。例如,若错误预算允许 10% 的失败率,则熔断器阈值可设为 15%~20%,这样熔断器在预算即将耗尽时提前介入,避免预算被完全突破。