← 返回题目列表

熔断器的状态机如何设计?

高频 中等 第 9 / 26 题 更新于 2026/09/30
熔断器状态机半开探测服务治理
学习 AI 实战项目

简化版

熔断器通常有 CLOSED、OPEN、HALF_OPEN 三态:关闭态统计失败或慢调用,达到阈值后打开并快速拒绝;等待冷却时间后进入半开,只放少量探测请求,成功则关闭,失败则重新打开。 工程关键是滑动窗口、最小请求数、探测并发和状态切换原子性,而不是只背三个状态名。

详细版

CLOSED 状态用计数或时间滑动窗口记录成功、异常、超时和慢调用。只有样本达到最小请求数才计算比例,避免 1 次失败就熔断;例如最近 10 秒至少 50 次调用,失败率达到 50% 才从 CLOSED 切到 OPEN。

OPEN 直接拒绝或走明确的 fallback,并记录下次允许探测的时间。到期后用 CAS 让一个线程完成 OPEN -> HALF_OPEN,半开态只准 5 个探测并禁止普通洪峰涌入;5 个全成功或成功比例达标才 CLOSED,任一关键失败可立即 OPEN。配置要按接口/下游隔离,并区分业务异常与系统异常。

完整版教学

一、熔断器保护什么

下游已过载时,继续发送请求会占用上游线程和连接,超时后重试还会增加压力。熔断器在本地记住近期失败事实,暂时停止无望调用,让下游获得恢复时间。它优化的是故障期间的资源消耗和失败延迟,不保证被调用服务恢复。

记忆钩子:CLOSED 是观察,OPEN 是止血,HALF_OPEN 是小流量验伤。

二、三态转换与并发控制

            失败/慢调用达阈值
   CLOSED --------------------> OPEN
      ^                           |
      | 探测达标                  | 冷却时间到
      |                           v
      +---------------------- HALF_OPEN
                     探测失败 ----> OPEN

状态和版本必须原子更新,否则很多线程可能同时发现冷却到期并发起探测。可用 CAS 抢占半开迁移权,或把 nextProbeAt 与状态放进同一原子对象。分布式共享熔断状态通常没有必要:每个实例按自己观察到的调用质量决策,能避免中心存储成为新依赖。

三、窗口决定“记住多少历史”

计数窗口保留最近 N 次,低流量下可能跨很久;时间窗口保留最近 T 秒,高流量下样本更多。桶化时间窗口能以固定内存维护统计,例如 10 个 1 秒桶组成 10 秒窗口。窗口过短会被瞬时尖峰触发,过长又会让恢复后的旧失败迟迟不退出。

failureRate = failed / total
slowRate    = calls(duration >= 800ms) / total
仅当 total >= minimumCalls 时判断阈值

四、哪些结果算失败

连接拒绝、超时和 5xx 通常计入系统失败;参数错误、权限拒绝等 4xx 多半是调用方问题,不应让下游熔断。慢调用即使最终成功,也可能持续占用资源,因此可以单独按慢调用比例打开。业务“库存不足”是正常结果,若误算为失败,大促时会把健康库存服务熔断。

结果是否通常计失败原因
connect timeout是依赖不可达或拥塞
HTTP 503是服务明确不可用
HTTP 400否请求本身错误
库存不足否业务语义结果
成功但耗时 2s计慢调用会造成资源堆积

五、半开探测为什么最容易写错

假设 OPEN 时积累了 5000 QPS 流量,冷却一到若全部放行,下游会遭遇第二次冲击。半开态应该有独立且很小的 permit,例如最多 5 个探测,其余仍快速拒绝。探测样本太少可能误判,可要求 5 次中至少 4 次成功且 P95 小于 300ms,再逐步恢复而非瞬间全开。

多实例会各自探测,100 个上游实例每个放 5 个就是 500 个请求。可加入随机冷却抖动、降低单实例探测数,或让服务发现层先只恢复少量流量,以控制聚合探测压力。

六、阈值与恢复参数怎样定

阈值应从 SLO、调用量与依赖容量反推。某接口平时 1000 QPS、错误率 0.1%,可以用 10s / minimumCalls=100 / failureRate=50% 起步;低频管理接口 10 秒只有 2 次请求,这组参数永远不会触发,应扩大窗口或使用连续失败阈值。

OPEN 冷却不是越长越安全:10 秒可快速恢复,但容易抖动;5 分钟会让已经恢复的依赖长期无流量。常见做法是失败后指数增加冷却上限,并在成功后逐步恢复基线。所有阈值必须通过故障演练验证。

七、fallback、观测与配置发布

fallback 必须符合业务语义:推荐可返回空列表或缓存,支付创建不能伪造“成功”。监控需展示各状态停留时间、状态切换次数、被拒数、原始失败率、慢调用率和半开结果,并把“熔断拒绝”与“下游调用失败”分开统计。

规则发布先影子计算,再按实例灰度。若把异常分类写错,可能全量误熔断;所以要有一键禁用和上一版本规则。熔断器本身的统计失败时应采取保守可解释策略,不能因为监控组件异常把全部业务锁死。

八、常见误区与追问

  • 误区:一次请求失败就应该熔断。 没有最小样本数会让偶发错误触发大范围拒绝。
  • 误区:OPEN 后定时自动变 CLOSED。 应先进入 HALF_OPEN 用受控真实请求验证恢复。
  • 误区:所有异常都计入失败率。 业务拒绝和调用方错误不代表依赖不健康。
  • 误区:fallback 一定能提升可用性。 错误的默认值可能把技术故障伪装成业务成功。
  • 追问:熔断和限流谁先执行? 通常先做本地参数/权限校验,再按治理链明确顺序;关键是避免被拒请求污染另一规则的统计。
  • 追问:如何避免多实例同时探测? 缩小单实例配额并加入随机抖动,必要时协调服务发现的恢复流量。
  • 追问:进程重启后状态是否恢复? 多数场景从 CLOSED 重新学习即可;若启动洪峰风险高,可用预热和保守初值,而非强依赖远端状态。

九、加强记忆

回答熔断状态机时按“统计—打开—冷却—试探—恢复”展开,再补四个边界:样本不足不判断、错误要分类、半开要限额、fallback 不能撒谎。最后给出窗口、阈值和探测数量的数字例子,就能说明状态转换何时发生、为何安全以及怎样验证。