防雪崩三件套:限流、熔断、服务降级

梳理限流算法、熔断状态与服务降级策略,说明三者如何协同防止服务雪崩,以及这些手段在单体与分布式架构中的作用。

· 8 min read · —

限流、熔断与服务降级是保障分布式系统高可用性的三大核心手段。它们各自解决的问题不同,但通常组合使用:限流管入口流量,熔断管出口调用,降级管失败兜底。


一、限流

单位时间内处理的请求数量设上限,防止流量突增压垮系统。

算法对比

算法原理特点
计数器固定窗口内计数,超阈值拒绝简单,但有临界突刺
滑动窗口把窗口切细,滚动统计平滑,精度较高
漏桶请求先入桶,匀速流出速率恒定,抗突发
令牌桶匀速生成令牌,有令牌才放行允许一定突发,最常用

策略:拒绝式(超限直接 429)· 排队式(入队等待)· 降级式(走兜底) 落地:网关层(Nginx / Spring Cloud Gateway / Kong)· 应用层(Sentinel / Guava RateLimiter / Resilience4j)· 分布式(Redis + Lua)


二、熔断

下游服务故障率过高时主动切断调用,避免调用方被拖垮,也给下游恢复时间。

三种状态

Closed(关闭)──错误率超阈值──> Open(打开)
      ↑                              │
      │                         等待冷却时间
      │                              ↓
      └──探测成功── Half-Open(半开)
                     │ 探测失败
                     ▼
                  回到 Open
  • Closed:正常放行,统计失败率
  • Open:快速失败,不真正调用下游
  • Half-Open:放少量探测请求,成功则恢复

关键参数:错误率阈值 · 慢调用比例 · 统计窗口 · 熔断时长 · 半开探测请求数

与限流的区别:限流控入口,防自己被打垮;熔断控出口,防被下游拖垮。


三、服务降级

系统资源不足或依赖故障时,牺牲非核心功能,保证核心功能可用。

降级方式:返回兜底数据(缓存/默认值/空列表)· 关闭非核心功能(推荐/评论/积分)· 异步化(改走 MQ)· 读降级(只读缓存不查库)

触发时机:熔断触发后 · 限流触发后 · 系统负载过高 · 依赖服务超时

降级 vs 熔断:熔断是机制(自动切断故障调用),降级是策略(切断后返回什么、牺牲什么)。


四、三者关系

用户请求 → [限流] ──超限──> 拒绝/排队/降级
                │
                ▼
         [调用下游]
                │
                ▼
          [熔断] ──故障率高──> 快速失败
                │
                ▼
          [降级] ──> 返回兜底/关闭非核心

一句话:限流挡住过多请求,熔断切断故障依赖,降级牺牲次要保主要。


进阶:为什么偏偏强调”分布式”?

为什么是保障分布式系统高可用性的三大核心手段,单体架构呢?

核心结论:这三大手段在单体架构里也能用,但必要性在分布式场景被急剧放大——从”可选优化”变成”生存必需”。

单体里也有类似手段

  • 限流:单体也会被突发流量打垮,所以也会做(如 Tomcat maxThreads)。
  • 熔断:本地方法一般不熔断,但调用外部依赖(DB / 第三方 API)时也会用。
  • 降级:数据库压力大时走缓存、关闭非核心功能,单体也会做。

严格说不是分布式独有,那为什么总被冠以”分布式高可用三大手段”?因为分布式把三个问题都”放大”了。

三大放大点

1. 网络调用取代本地调用 → 故障面爆炸

调用方式故障特征
本地方法不会超时(除非死循环)、不会抖动、失败立刻抛异常
跨网 RPC可能超时/丢包/乱序,请求发出去了但不知道对方有没有执行,慢下游会耗尽调用方线程池引发雪崩

熔断在分布式里成为刚需,本质就是因为这个不确定性。

2. 服务依赖变成网状 → 故障会级联

单体故障”全有或全无”,分布式是依赖图 A → B → C → D,一环慢则反向传播:

D 慢 → C 线程堆积 → B 线程堆积 → A 线程堆积 → 整个系统雪崩

熔断切断传播链、限流防止入口放大级联压力、降级保证链路断了还能返回点什么。

3. 容量边界从一台机器变成一群机器

单体扩容 = 换更强的机器(垂直扩展)。分布式 = 多实例 + 负载均衡,新问题:热点实例先垮、故障实例流量转嫁剩余实例(惊群/重试风暴)、重试放大流量(1 次失败 → 3 次重试 → ×3)。

→ 需要更精细的限流(集群+单机)和熔断抑制重试放大。

本质区别:单体”自己扛”,分布式”协作扛”

维度单体分布式
调用本地方法网络 RPC
故障形态全有或全无部分失败、不确定性
故障传播进程内,范围有限跨服务级联,可雪崩
容量单机资源集群 + LB + 热点
重试基本无影响会放大流量
一致性本地事务分布式事务/最终一致
三件套可选优化生存必需

单体里,三件套是”锦上添花”;分布式里,它们是”防止雪崩的护栏”。

为什么偏偏是这三个?

分布式高可用手段很多(超时 / 重试 / 隔离 / 幂等 / 异步 / 多副本……),但限流、熔断、降级独占封面,是因为它们覆盖了流量的三个关键控制点:

入口 ──[限流]──> 调用 ──[熔断]──> 失败后 ──[降级]──> 兜底
  • 限流:控制”进来多少”
  • 熔断:控制”要不要发出去”
  • 降级:控制”发不出去怎么办”

三者构成一条完整的流量韧性防线。其他手段(重试、隔离、超时)是这条防线的补充,不是替代。

文章目录