什么是熔断降级

熔断降级,说白了就是给系统装一个“自动保险丝”。

微服务架构里,一个服务出问题,调用方会一直等、一直重试。线程池被耗尽,请求堆积,整个链路跟着崩。我早年在一个支付项目里就吃过这个亏——某个第三方渠道响应慢了几秒,结果所有线程卡住,其他正常渠道也进不去了。那次故障让我彻底记住了:不能迷信超时,必须上熔断。

熔断的核心思想很简单:
检测到故障率超过阈值,直接拒绝新请求,快速失败。等一段时间后,尝试放行少量请求,看上游是否恢复。恢复就关闭熔断器,否则继续保持断开。

熔断降级的起源

这个概念最早来自电路中的断路器(Circuit Breaker)。Michael Nygard 在《Release It!》里把它引入软件设计,后来 Netflix 的 Hystrix 发扬光大。现在像 Sentinel、Resilience4j 都是常见的实现。

我习惯把熔断和降级放在一起讲,但两者其实是两码事:

  • 熔断 —— 切断调用链,保护下游不被拖垮。
  • 降级 —— 熔断后,返回一个兜底结果(比如默认值、缓存数据、错误提示)。

降级是熔断后的处理动作,没有降级的熔断等于裸奔。你想想看,如果熔断了什么都不返回,调用方照样会出错,那熔断的意义就少了一半。

我的习惯:给每个远程调用都配一个降级方法。哪怕只返回 null 或空列表,也比卡死强。

适用场景归纳

不是所有地方都需要熔断降级。我总结了几类“刚需场景”:

场景 典型例子 为什么需要
依赖不稳定 第三方 API、数据库、缓存 对方可能瞬间变慢或挂掉
高并发冲击 秒杀、大促、突发热点 系统来不及扩容时,先保核心链路
资源有限 线程池、连接池、CPU 防止雪崩,保护自身不被耗尽
级联故障 调用链 A→B→C→D 下游出问题,熔断可以快速阻断,避免波及上游
长时间无响应 慢 SQL、网络延迟、死锁 等超时太浪费,直接熔断并返回降级数据

我曾经踩过的坑:给整个服务配了一个全局熔断规则,结果一个非核心接口波动导致核心接口也被切断。后来改用资源粒度——每个远程调用、每个接口单独配置熔断阈值,互不影响。

熔断器的三种状态

理解状态机是掌握熔断的基础。我画了一张图,把关键路径都标出来了:

熔断器状态机 CLOSED(关闭) 正常调用,计数 故障率 ≥ 阈值 OPEN(断开) 拒绝请求,快速失败 等待时间到 HALF-OPEN(半开) 放行试探请求 请求成功 请求失败 核心指标 时间窗口 · 阈值 · 试探数

这张图说明了几件事:

  • Closed 状态统计请求失败率,达到阈值就跳到 Open。
  • Open 状态直接拒绝请求,经过一个冷却时间(比如 10 秒)进入 Half-Open。
  • Half-Open 放少量请求试探。如果成功,回到 Closed;如果失败,回到 Open 重新计时。

关键点:Half-Open 阶段放的请求数要合理。我一般设成 3~5 个,太多可能把下游压垮,太少又测不出恢复情况。

什么时候不该用熔断?

我遇到过团队把熔断滥用的案例。下面几种情况不适合:

  • 本地方法调用 —— 熔断只针对远程或跨进程调用。本地方法出错应该直接 try-catch 或重试。
  • 要求强一致性的交易链路 —— 熔断会导致请求被丢弃,如果一定要超时+回滚,考虑其他方案。
  • 流量极低的服务 —— 一分钟都调不了几次,窗口数据不具统计意义,熔断效果有限。

切记:熔断不是银弹。我见过有人给 Redis 加了熔断,结果缓存查询失败直接返回 null,业务逻辑崩了。降级策略一定要和业务方确认好。

好了,第一章先聊到这里。理解了熔断是什么、用在哪儿、状态怎么转,后面再深入触发条件和恢复技巧就顺了。