什么是熔断降级
熔断降级,说白了就是给系统装一个“自动保险丝”。
微服务架构里,一个服务出问题,调用方会一直等、一直重试。线程池被耗尽,请求堆积,整个链路跟着崩。我早年在一个支付项目里就吃过这个亏——某个第三方渠道响应慢了几秒,结果所有线程卡住,其他正常渠道也进不去了。那次故障让我彻底记住了:不能迷信超时,必须上熔断。
熔断的核心思想很简单:
检测到故障率超过阈值,直接拒绝新请求,快速失败。等一段时间后,尝试放行少量请求,看上游是否恢复。恢复就关闭熔断器,否则继续保持断开。
熔断降级的起源
这个概念最早来自电路中的断路器(Circuit Breaker)。Michael Nygard 在《Release It!》里把它引入软件设计,后来 Netflix 的 Hystrix 发扬光大。现在像 Sentinel、Resilience4j 都是常见的实现。
我习惯把熔断和降级放在一起讲,但两者其实是两码事:
- 熔断 —— 切断调用链,保护下游不被拖垮。
- 降级 —— 熔断后,返回一个兜底结果(比如默认值、缓存数据、错误提示)。
降级是熔断后的处理动作,没有降级的熔断等于裸奔。你想想看,如果熔断了什么都不返回,调用方照样会出错,那熔断的意义就少了一半。
我的习惯:给每个远程调用都配一个降级方法。哪怕只返回 null 或空列表,也比卡死强。
适用场景归纳
不是所有地方都需要熔断降级。我总结了几类“刚需场景”:
| 场景 | 典型例子 | 为什么需要 |
|---|---|---|
| 依赖不稳定 | 第三方 API、数据库、缓存 | 对方可能瞬间变慢或挂掉 |
| 高并发冲击 | 秒杀、大促、突发热点 | 系统来不及扩容时,先保核心链路 |
| 资源有限 | 线程池、连接池、CPU | 防止雪崩,保护自身不被耗尽 |
| 级联故障 | 调用链 A→B→C→D | 下游出问题,熔断可以快速阻断,避免波及上游 |
| 长时间无响应 | 慢 SQL、网络延迟、死锁 | 等超时太浪费,直接熔断并返回降级数据 |
我曾经踩过的坑:给整个服务配了一个全局熔断规则,结果一个非核心接口波动导致核心接口也被切断。后来改用资源粒度——每个远程调用、每个接口单独配置熔断阈值,互不影响。
熔断器的三种状态
理解状态机是掌握熔断的基础。我画了一张图,把关键路径都标出来了:
这张图说明了几件事:
- Closed 状态统计请求失败率,达到阈值就跳到 Open。
- Open 状态直接拒绝请求,经过一个冷却时间(比如 10 秒)进入 Half-Open。
- Half-Open 放少量请求试探。如果成功,回到 Closed;如果失败,回到 Open 重新计时。
关键点:Half-Open 阶段放的请求数要合理。我一般设成 3~5 个,太多可能把下游压垮,太少又测不出恢复情况。
什么时候不该用熔断?
我遇到过团队把熔断滥用的案例。下面几种情况不适合:
- 本地方法调用 —— 熔断只针对远程或跨进程调用。本地方法出错应该直接 try-catch 或重试。
- 要求强一致性的交易链路 —— 熔断会导致请求被丢弃,如果一定要超时+回滚,考虑其他方案。
- 流量极低的服务 —— 一分钟都调不了几次,窗口数据不具统计意义,熔断效果有限。
切记:熔断不是银弹。我见过有人给 Redis 加了熔断,结果缓存查询失败直接返回 null,业务逻辑崩了。降级策略一定要和业务方确认好。
好了,第一章先聊到这里。理解了熔断是什么、用在哪儿、状态怎么转,后面再深入触发条件和恢复技巧就顺了。