级联失败
雪崩、线程池耗尽、retry storm。
35 分钟
级联失败
一个组件变慢或挂掉,若调用方 无限等待、无限重试,会把线程、连接池、队列 逐级拖垮——这就是 级联失败(Cascading Failure),也叫 故障雪崩。
学习目标
- 理解 retry storm、线程池耗尽、连接池饥饿
- 识别 CodeRoadMap 单体内的级联路径
- 知道熔断与限流如何截断传播(见 rel-circuit)
雪崩直觉
MySQL 变慢 (500ms → 30s)
│
▼
backend 连接池占满 (Hikari 默认 10)
│
▼
所有 API 阻塞等待 DB ──► Tomcat 线程满
│
▼
Nginx 502/504 ──► 用户刷新 ──► 流量 ×2 ──► retry storm
慢依赖比死依赖更危险:进程还在,但资源被占光。
常见放大器
| 放大器 | 机制 | 对照 |
|---|---|---|
| 同步链路过长 | A→B→C 任一慢则全慢 | ip-api-composition |
| 无超时 | 默认等 forever | rel-timeout |
| 重试风暴 | 客户端 + 网关 + 服务三重重试 | rel-retries |
| 共享资源 | 一个慢查询拖死整库连接 | pg-transactions 长事务 |
截断策略
检测(延迟/错误率上升)
→ 超时(释放线程)
→ 有限重试 + 退避
→ 熔断 OPEN(快速失败)
→ 降级(缓存/默认值)
→ 限流(保护核心路径)
微服务实践见 sc-circuit-breaker;模式层见 ip-circuit。
宝塔单机注意
backend 与 MySQL 同机时,磁盘 I/O 饱和 会同时拖慢 DB 与应用——监控 CPU、iowait、连接数(prom-metrics)。
练习
- 画出「用户刷新加剧雪崩」的反馈环
- 说明为何「加机器」不能解决连接池耗尽
- 列举 CodeRoadMap 上应设超时的两个调用点