断路器是请求发起前的“守门人”,含关闭、打开、半开三态:关闭时统计失败,达阈值转打开;打开时直接回退并计时;计时结束进半开,试探成功则恢复关闭,失败则重置。

核心是把断路器作为请求发起前的“守门人”,而不是事后补救工具。它不改变请求逻辑,只决定该不该发、发了怎么收、失败后怎么缓。
明确断路器的三种状态与切换逻辑
断路器不是开关,而是一个带记忆和计时的状态机:
- 关闭态(Closed):正常放行请求,同时统计每次调用结果。失败达到阈值(如10秒内5次失败)就跳转到打开态
- 打开态(Open):不发请求,直接返回预设回退值(如空数据、缓存、默认响应),并启动一个静默计时器(如60秒)
- 半开态(Half-Open):静默期结束后,允许极少量试探请求(如1–2个)。全成功则恢复关闭态;任一失败,重置计时器并回到打开态
确保断路器统计的是“原始请求”,而非重试结果
如果组件还带重试机制,必须让断路器包裹整个重试块,而不是嵌套在重试内部。否则熔断器看到的永远是“最后一次是否成功”,失去对服务真实健康度的判断力。
正确组合方式(以 Java Resilience4j 为例):
- 先定义重试策略:用
IntervalFunction.ofExponentialBackoff实现指数退避(如首次等100ms,第二次200ms,第三次400ms…) - 再定义断路器:设置
failureRateThreshold=50、slidingWindowSize=10(滑动窗口大小决定统计精度)、waitDurationInOpenState=60s - 最后用
Decorators.ofSupplier(...).withRetry(retry).withCircuitBreaker(cb).decorate()组合——注意顺序不能颠倒
适配异步执行环境的关键细节
在 Node.js 或 Python 等异步运行时中,断路器状态检查必须与事件循环对齐:
- 每次尝试请求前都调
cb.allow(),不能只检查一次就进重试循环 - 请求失败后立即调
cb.failure(),成功才调cb.success(),避免状态滞后 - Go 中使用
gobreaker时,backoff.ExponentialBackOff的InitialInterval和MaxInterval必须显式设置,否则默认1s/60s可能过长 - 避免在
await或Promise链中漏掉状态更新,比如未捕获的 rejected promise 会让断路器错过失败信号
配合回退策略提升用户体验
断路器跳闸后不能只抛错,应提供有业务意义的兜底:
- 返回本地缓存数据(Cache-Aside 模式联动)
- 降级为简化响应(如只返回 ID 列表,不加载详情)
- 触发告警或日志标记,便于运维快速感知
- 对关键路径可叠加 Bulkhead(隔板)隔离资源,防止单个断路器反复触发拖垮线程池










