熔断器三种状态详解:Closed、Open、Half-Open

熔断器(Circuit Breaker)是分布式系统中防止级联故障的关键模式。其核心在于通过有限状态机管理调用链路的状态转换,避免对已故障的服务持续无效调用。标准熔断器包含三种状态:关闭(Closed)、打开(Open)、半开(Half-Open)。理解每种状态的定义及转换条件是设计高可用系统的前提。

核心原则:熔断器不是“熔断后永久断开”,而是通过半开状态主动探测恢复时机,实现故障隔离与自动恢复的闭环。

2.1 三种状态定义与行为

状态 定义 调用行为 典型场景
Closed(关闭) 熔断器处于正常通行状态,所有请求直接转发给下游服务。 正常调用,同时统计失败率/超时率。 服务健康,调用成功率高于阈值。
Open(打开) 熔断器判定下游服务不可用,直接拒绝请求,快速失败。 请求立即返回错误(如 503),不发起实际调用。 失败率超过阈值,触发熔断保护。
Half-Open(半开) 熔断器在 Open 状态超时后进入试探阶段,允许有限请求通过。 放行少量探测请求,根据结果决定恢复或继续熔断。 Open 状态超时到期,系统尝试恢复。

2.2 状态转换条件与触发机制

三种状态之间的转换由计数器、时间窗口和阈值共同驱动。下图展示了完整的转换闭环:

熔断器三种状态转换图 Closed 关闭状态 Open 打开状态 Half-Open 半开状态 失败率 ≥ 阈值 (如 50%) 超时时间到期 (如 30s) 探测请求成功 (恢复计数) 探测请求失败 (重置超时) 正常调用 滑动窗口统计

2.3 转换条件详细说明

2.3.1 Closed → Open(关闭 → 打开)

  • 触发条件:在滑动时间窗口内(如 10s),请求失败率超过预设阈值(如 50%),且请求总数达到最小样本量(如 5 次)。
  • 行为:熔断器立即切换为 Open 状态,后续请求直接快速失败,不调用下游。
  • 典型配置:
# 示例:Hystrix 风格配置
circuitBreaker.requestVolumeThreshold: 5      # 最小请求数
circuitBreaker.errorThresholdPercentage: 50   # 失败率阈值
metrics.rollingStats.timeInMilliseconds: 10000 # 滑动窗口 10s

2.3.2 Open → Half-Open(打开 → 半开)

  • 触发条件:熔断器在 Open 状态持续一段休眠时间(如 30s)后,自动进入 Half-Open 状态。
  • 行为:允许有限数量的探测请求通过(通常为 1~3 个),其余请求仍被拒绝。
  • 关键参数:
# 休眠时间与探测请求数
circuitBreaker.sleepWindowInMilliseconds: 30000  # 休眠 30s
circuitBreaker.halfOpenMaxRequests: 3            # 最多放行 3 个探测请求

2.3.3 Half-Open → Closed / Open(半开 → 关闭 / 打开)

  • 恢复条件(→ Closed):所有探测请求均成功,且响应时间正常。熔断器重置计数器,回到 Closed 状态。
  • 再次熔断条件(→ Open):任意探测请求失败或超时。熔断器立即回到 Open 状态,并重置休眠计时器,等待下一次 Half-Open 尝试。
  • 避坑提示:探测请求的超时时间应短于正常调用超时,避免探测请求长时间挂起阻塞线程。
常见误区:Half-Open 状态不是“放行所有请求”,而是“放行少量探测请求”。如果配置的 halfOpenMaxRequests 过大,可能导致下游服务被突发流量压垮,失去熔断保护意义。

2.4 状态转换参数对比表

转换路径 触发条件 关键参数 典型值
Closed → Open 失败率 ≥ 阈值 & 请求数 ≥ 最小样本量 errorThresholdPercentage, requestVolumeThreshold 50%, 5 次
Open → Half-Open 休眠时间到期 sleepWindowInMilliseconds 30000 ms
Half-Open → Closed 所有探测请求成功 halfOpenMaxRequests 3 次
Half-Open → Open 任意探测请求失败 (无额外参数,复用原阈值) —

2.5 状态转换的工程实践要点

  • 滑动窗口 vs 固定窗口:推荐使用滑动窗口统计失败率,避免固定窗口在边界处产生毛刺。
  • 最小样本量保护:设置 requestVolumeThreshold 防止低流量时误触发熔断。
  • 探测请求隔离:Half-Open 的探测请求应使用独立的线程池或超时配置,避免与正常请求竞争资源。
  • 状态持久化:在分布式环境中,熔断器状态建议存储在本地内存(如 AtomicReference),而非外部存储,避免网络开销影响熔断时效。
面试高频题:“为什么需要 Half-Open 状态?”——因为 Open 状态无法感知下游是否恢复,Half-Open 通过小流量探测实现安全恢复,避免“惊群效应”或“雪崩恢复”。