防雪崩三件套:限流、熔断、服务降级
梳理限流算法、熔断状态与服务降级策略,说明三者如何协同防止服务雪崩,以及这些手段在单体与分布式架构中的作用。
限流、熔断与服务降级是保障分布式系统高可用性的三大核心手段。它们各自解决的问题不同,但通常组合使用:限流管入口流量,熔断管出口调用,降级管失败兜底。
一、限流
单位时间内处理的请求数量设上限,防止流量突增压垮系统。
算法对比
| 算法 | 原理 | 特点 |
|---|---|---|
| 计数器 | 固定窗口内计数,超阈值拒绝 | 简单,但有临界突刺 |
| 滑动窗口 | 把窗口切细,滚动统计 | 平滑,精度较高 |
| 漏桶 | 请求先入桶,匀速流出 | 速率恒定,抗突发 |
| 令牌桶 | 匀速生成令牌,有令牌才放行 | 允许一定突发,最常用 |
策略:拒绝式(超限直接 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 + 热点 |
| 重试 | 基本无影响 | 会放大流量 |
| 一致性 | 本地事务 | 分布式事务/最终一致 |
| 三件套 | 可选优化 | 生存必需 |
单体里,三件套是”锦上添花”;分布式里,它们是”防止雪崩的护栏”。
为什么偏偏是这三个?
分布式高可用手段很多(超时 / 重试 / 隔离 / 幂等 / 异步 / 多副本……),但限流、熔断、降级独占封面,是因为它们覆盖了流量的三个关键控制点:
入口 ──[限流]──> 调用 ──[熔断]──> 失败后 ──[降级]──> 兜底
- 限流:控制”进来多少”
- 熔断:控制”要不要发出去”
- 降级:控制”发不出去怎么办”
三者构成一条完整的流量韧性防线。其他手段(重试、隔离、超时)是这条防线的补充,不是替代。