熔断、降级、重试分别解决什么问题?重试有哪些注意点?
结论先行:三者都是稳定性手段但层次不同:熔断是“打不过就快速失败”——下游失败率达到阈值(如 5 秒内失败率 50%)就断路,后续请求直接走 fallback,防止故障放大成雪崩;降级是“保核心、弃边缘”——资源不足时主动牺牲非核心能力(返回兜底数据、关停耗资源特性);重试是“偶发抖动就再来一次”——对瞬时故障提升成功率。注意:重试只适用于幂等操作与“下游还能扛”的场景,否则会放大故障。
三者对比表
| 手段 | 面向 | 触发条件 | 典型动作 |
|---|---|---|---|
| 熔断 | 下游故障 | 失败率/慢调用率超阈值 | 断路 + fallback,半开探测恢复 |
| 降级 | 自身资源不足 | 人工开关/自动规则 | 返回兜底、只保核心链路 |
| 重试 | 瞬时抖动 | 超时、特定异常 | 限次数 + 退避 + 幂等约束 |
熔断状态机
CLOSED(正常放行) --失败率超阈值--> OPEN(直接短路)
OPEN --冷却时间到--> HALF_OPEN(放少量探测流量)
HALF_OPEN --探测成功--> CLOSED;--探测失败--> OPEN
带退避的重试(示意)
for (int i = 1; i <= 3; i++) { // 最多重试 3 次
try {
return rpc.call();
} catch (TimeoutException e) {
// 指数退避 + 随机抖动,避免重试风暴
Thread.sleep(100L * i + ThreadLocalRandom.current().nextInt(50));
}
}
throw new BizException("下游暂不可用,已熔断/放弃");
重试注意点
- 只重试幂等操作(查询、幂等键写入),否则可能重复扣款、重复下单;
- 重试必须限次数(1~3 次)并配合指数退避与抖动;
- 下游已超时/过载时不要盲目重试,应先让熔断器介入;
- 调用超时要小于重试总预算,避免线程被长时间占用拖垮线程池。
常见追问 / 记忆点
- 追问:熔断和限流有什么区别?答:限流保护自己不被流量打垮;熔断保护自己不被故障下游拖垮,两者常配合使用。
- 追问:为什么重试要加随机抖动?答:同步重试会让所有失败请求在同一时刻再打过去形成“重试风暴”,抖动打散请求相位。
- 记忆点:熔断管“下游坏了别硬撑”,降级管“资源不够砍次要”,重试管“抖一下再来”,且必须幂等 + 限次 + 退避。