一个服务出故障,为什么整个网站没跟着崩?

发布 · 视频 2:09 · 约 2 分钟读完 · #后端#熔断#高可用

章节

  1. 0:00没跟着崩
  2. 0:15雪崩
  3. 0:41电闸跳闸
  4. 1:14关闭是通,打开是断
  5. 1:28试着合闸
  6. 1:44回顾

快捷键:K/空格 播放暂停 · J/L 上/下一章 · ↑/↓ 切换章节

大促时某个后台服务出了故障,整个网站却没跟着崩,靠的是熔断(circuit breaker):发现某个依赖持续出错,就暂时不再调用它,避免故障扩散。它的思路和家里的电闸一样。下面分 6 步讲清楚。

6 步看懂熔断

1. 没跟着崩#▶ 从这里看

  • 一个网站背后是很多服务互相调用。某个服务出故障很常见,关键是别让它把别的服务一起拖下水。

2. 雪崩#▶ 从这里看

  • 打开结算页时,系统要同步调用运费险服务(这里只是举例),看这一单能不能加运费险。运费险服务故障、迟迟不响应,结算页的线程和连接就被一直占着。
  • 等待的请求越积越多,订单服务也不可用,再影响支付。这叫雪崩,也叫级联故障(cascading failure)。1

3. 电闸跳闸#▶ 从这里看

  • 超时:每次调用设等待上限,到点放弃。必须有,但高峰时每个请求仍要白等一次。2
  • 熔断:熔断器统计最近的调用结果,失败率超过阈值就跳闸,之后的请求不再调用运费险服务,直接快速失败、马上返回。这既保护了结算和下单,也给运费险服务恢复的时间。3
  • 示例参数(仅示例,需按流量和业务调整):最近 100 次调用失败率达到 50% 就打开,断开 30 秒(Resilience4j 默认是 60 秒)。
  • 熔断不能代替超时,两者要一起用。

4. 关闭是通,打开是断#▶ 从这里看

  • 关闭(Closed):正常调用,同时统计失败率。
  • 打开(Open):已跳闸,直接拒绝调用。
  • 反直觉之处:和电闸一样,「合上(关闭)」才通电,「跳开(打开)」才断电。

5. 试着合闸#▶ 从这里看

  • 半开(Half-Open):打开一段时间后,放少量请求去试探。成功就回到关闭,恢复正常调用;失败就重新打开,过一阵再试。31

6. 回顾#▶ 从这里看

  • 熔断后结算页少显示运费险这一项、下单照常,这一步是降级(见上期)。
  • 熔断适合弱依赖(挂了不影响主流程,如运费险);库存这类强依赖熔断后不能「降级继续下单」:校验不了库存就快速失败、提示稍后再试,不能跳过校验。45
  • 三者区别:限流管进来的流量;熔断隔离出故障的依赖;降级牺牲次要功能、保住核心功能。
  • 「扛住高峰」五招:消息队列、限流、幂等、降级、熔断。

参考资料

Footnotes

  1. Microsoft Azure Architecture Center,《Circuit Breaker pattern》(持续更新的官方文档,访问于 2026-10-13):https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker ↩ ↩2

  2. AWS Builders’ Library,《Timeouts, retries, and backoff with jitter》(2019,仅参考):https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/ ↩

  3. Resilience4j 官方文档,《CircuitBreaker》(持续更新,访问于 2026-10-13):https://resilience4j.readme.io/docs/circuitbreaker ↩ ↩2

  4. 京东云开发者社区,《【稳定性】稳定性建设之依赖设计》(2024-02-23):https://developer.jdcloud.com/article/3670 ↩

  5. Sentinel 官方文档《熔断降级》(持续更新,访问于 2026-10-14):https://sentinelguard.io/zh-cn/docs/circuit-breaking.html ↩

幕后

这部片子完全由代码生成。