API 网关如何做熔断降级?
简化版
网关熔断降级用来防止后端服务故障扩散、拖垮整个系统。熔断:当网关检测到某个后端服务错误率过高或响应过慢时,像保险丝一样「跳闸」——一段时间内不再把请求转发给这个故障服务,直接快速失败,避免大量请求堆积、避免故障蔓延;一段时间后试探性放行少量请求,若恢复了就关闭熔断。降级:熔断触发(或调用失败)后,返回一个兜底响应(默认值、友好提示、缓存旧数据),保证用户不会看到错误、系统有损但可用。Spring Cloud Gateway 通过 CircuitBreaker 过滤器(集成 Resilience4j 或 Sentinel)实现。
详细版
熔断的三个状态(断路器模式):
错误率/慢调用超阈值
关闭(Closed) ───────────────→ 打开(Open)
↑正常放行 │ 直接快速失败,不调后端
│ │ 等待一段时间
│ 试探成功 ↓
└──────── 半开(Half-Open) ←─┘
放行少量试探请求
失败→回到 Open
- Closed(关闭):正常状态,请求正常转发;统计错误率/慢调用。
- Open(打开):熔断触发,不再转发请求给故障服务,直接走降级;持续一段时间。
- Half-Open(半开):等待期过后,放行少量试探请求——成功则回到 Closed(恢复),失败则回到 Open(继续熔断)。
Spring Cloud Gateway 配置(Resilience4j):
filters:
- name: CircuitBreaker
args:
name: orderCircuitBreaker
fallbackUri: forward:/fallback/order # 熔断后转发到降级处理
完整版教学
一、为什么需要熔断降级:防止故障扩散
微服务是一条调用链——网关 → 服务 A → 服务 B → 数据库。如果某个下游服务(比如服务 B)故障了、或响应极慢,会发生什么?
- 调用它的请求大量堆积、阻塞等待。
- 调用方(服务 A、网关)的线程/连接被占满,自己也被拖垮。
- 上游继续受影响……故障像雪崩一样层层蔓延,最终整个系统瘫痪。这叫级联故障 / 服务雪崩。
熔断降级就是为了阻断这种蔓延:当发现某个服务出问题时,果断「断开」对它的调用(熔断),并返回兜底结果(降级),把故障隔离在局部,保护整个系统的可用性。核心思想是**「快速失败 + 有损服务」好过「慢慢拖死 + 全部瘫痪」**。
二、熔断:像保险丝一样跳闸
熔断(Circuit Breaker,断路器) 借鉴了电路里保险丝的概念——电流过大时保险丝熔断,切断电路,保护电器。软件里:当对某个服务的调用错误率/慢调用比例超过阈值时,断路器「跳闸」,一段时间内不再调用这个服务,直接快速失败。
断路器的三个状态是核心(面试常考):
- Closed(关闭,正常):断路器闭合,请求正常转发给后端。同时统计调用的成功/失败/耗时。当错误率或慢调用比例超过阈值(如 10 秒内错误率 > 50%),断路器跳到 Open。
- Open(打开,熔断中):断路器断开,所有请求不再转发给故障服务,直接快速失败 / 走降级。这样不再有请求去堆积、拖累系统。持续一个等待时间(如 30 秒)。
- Half-Open(半开,试探):等待时间过后,断路器进入半开,放行少量试探请求去调用服务:
- 如果这些请求成功(服务恢复了)→ 断路器回到 Closed,恢复正常。
- 如果还是失败(服务没恢复)→ 断路器回到 Open,继续熔断,再等一段时间。
这个「Closed → Open → Half-Open → Closed/Open」的循环,让系统能自动熔断故障服务、并自动探测恢复,无需人工干预。
三、降级:提供兜底响应
熔断解决了「不再调用故障服务」,但请求总得有个响应——不能让用户干等或看到 500 错误。降级(Fallback) 就是在熔断触发(或调用失败)时,返回一个兜底的响应:
- 返回默认值 / 友好提示:如「系统繁忙,请稍后重试」,或一个合理的默认结果。
- 返回缓存 / 旧数据:用之前缓存的数据兜底。
- 返回静态兜底内容。
Spring Cloud Gateway 里通过 fallbackUri 指定降级处理——熔断时把请求转发到一个降级接口,由它返回兜底响应。这样即使后端服务挂了,用户得到的是「有损但友好」的响应,而不是错误或超时——系统整体保持可用。
四、Spring Cloud Gateway 的实现
Spring Cloud Gateway 通过 CircuitBreaker 过滤器实现熔断降级,底层可集成:
- Resilience4j:Spring 官方推荐的容错库(替代已停更的 Hystrix),提供断路器、限流、重试、舱壁等。配置断路器的错误率阈值、等待时间、滑动窗口等。
- Sentinel:Spring Cloud Alibaba 的流量防护组件,提供更丰富的熔断降级规则(按慢调用比例、异常比例、异常数熔断)+ 限流,还有可视化控制台,国内常用。
配置上,给路由加 CircuitBreaker 过滤器,指定断路器名字和 fallbackUri(降级地址),熔断触发时请求转到降级处理。
五、熔断、降级、限流的配合
熔断降级常和限流一起构成完整的流量防护体系(见「网关限流」专题):
- 限流:控制入口流量,超过阈值的快速失败——防止系统被过量请求压垮(针对流量大)。
- 熔断:切断对故障依赖的调用——防止故障扩散/雪崩(针对下游故障)。
- 降级:熔断或失败后返回兜底——保证有损可用(兜底体验)。
三者分工:限流管「进来的太多」、熔断管「依赖坏了」、降级管「坏了之后给什么」。网关作为入口,是集中实施这三大防护的关键位置。
六、常见误区与追问
这道题面试时最容易丢分的地方,是把「网关熔断降级」答成一段泛泛的组件介绍。更稳的答法是先给结论,再沿着 统一流量入口链路 拆清楚流程,最后补上异常场景、数字边界和选型取舍。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心定义 | 网关熔断是在后端服务异常比例或延迟过高时停止转发,返回降级响应,防止故障扩散 | 不要停在名词解释 |
| 流程机制 | 统计滑动窗口指标 -> 错误率或慢调用超阈值 -> 进入熔断打开状态 -> 请求直接降级 -> 半开少量探测 -> 成功则关闭失败则继续打开 | 说明谁触发、谁存储、谁通知、谁兜底 |
| 工程取舍 | 例如 10 秒窗口内请求数超过 100 且错误率超过 50%,熔断 30 秒后再半开探测 | 网关适合收口横切能力,但不能把业务逻辑堆到网关,否则会形成新的复杂单体 |
网关熔断降级 面试拆解:
1. 统计滑动窗口指标
2. 错误率或慢调用超阈值
3. 进入熔断打开状态
4. 请求直接降级
5. 半开少量探测
6. 成功则关闭失败则继续打开
记忆钩子:先拆路由、过滤器、鉴权、限流、熔断、灰度,再说明网关和业务服务的边界;回答时一定要落到题目中的「网关熔断降级」,不要把相邻中间件的能力混着讲。
- 误区:熔断就是限流。 限流控制流量大小,熔断根据下游健康状况阻断调用。
- 误区:熔断后应该一直拒绝。 熔断需要半开探测,确认下游恢复后关闭。
- 误区:降级响应可以随便返回。 降级要符合业务语义,例如返回缓存、默认值或明确的稍后重试提示。
- 追问:熔断指标看什么? 错误率、慢调用比例、并发数、超时和最小请求数。
- 追问:网关熔断和服务内熔断怎么配合? 网关保护入口,服务内保护具体依赖,两层关注点不同。
- 追问:半开状态有什么作用? 用少量真实请求探测下游是否恢复,避免全量流量立即打回去。
七、加强记忆
网关熔断降级防止后端故障扩散、服务雪崩(下游故障 → 请求堆积 → 拖垮调用方 → 层层蔓延)。熔断(断路器,像保险丝) 三状态:Closed(正常转发+统计,错误率/慢调用超阈值则跳 Open)→ Open(熔断,不转发给故障服务、直接快速失败/降级,持续一段时间)→ Half-Open(放少量试探请求,成功回 Closed 恢复、失败回 Open 继续熔断)——自动熔断 + 自动探测恢复。降级(Fallback):熔断/失败时返回兜底响应(默认值/友好提示/缓存旧数据),保证「有损但可用」。Spring Cloud Gateway 用 CircuitBreaker 过滤器 + fallbackUri,底层集成 Resilience4j 或 Sentinel。与限流配合:限流管入口流量、熔断切故障依赖、降级给兜底。核心思想:快速失败 + 有损服务,好过慢慢拖死 + 全部瘫痪。口诀:熔断三态自动跳闸恢复、降级给兜底、限流熔断降级三件套护系统。