2.2 限流熔断与降级兜底


2.2 限流熔断与降级兜底

本节摘要:限流、熔断、降级是高并发的三板斧,它们共同构成系统的兜底网。本节讲限流的四种算法(计数器、滑动窗口、令牌桶、漏桶)的原理和差别,熔断器的三状态机和恢复机制,降级的策略选择,以及三者怎么配合形成纵深防御。核心是理解每种手段卡的是什么问题、参数怎么定、代价是什么。

学习目标

阅读完本节,你应当能够:

  1. 说清四种限流算法的原理、优缺点和适用场景
  2. 解释令牌桶和漏桶的差别,以及为什么令牌桶更常用
  3. 描述熔断器的关闭、打开、半开三状态及转换条件
  4. 设计降级策略,区分核心与非核心功能
  5. 说清限流熔断降级三者怎么配合形成兜底网

一、问题与直觉

高并发系统最怕两种情况。第一种,流量远超系统承载能力,所有请求挤在一起,资源耗尽,整个系统瘫痪。第二种,某个下游依赖故障或变慢,调用方傻等,线程池被占满,连锁把调用方也拖死,故障像多米诺骨牌一样蔓延。

这两种情况,光靠加机器防不住,因为它们是流量和故障的无序蔓延。要防住它们,得主动干预:流量太大就限流(主动拒绝超量的),下游坏了就熔断(快速失败不傻等),实在扛不住就降级(牺牲非核心保核心)。这就是三板斧的来历——它们不是可选的优化,而是高并发系统的保命装置。

三板斧各管一个问题,但单用一个都不够。只限流不熔断,下游慢照样拖死你;只熔断不降级,熔断后用户看到一片空白;只降级不限流,流量大到系统直接挂,连降级的机会都没有。三者必须配合,形成纵深防御。

二、核心原理

2.1 限流:四种算法

限流的核心是控制请求速率,超过阈值的请求被拒绝或排队。实现限流有四种经典算法。

计数器算法:在一个时间窗口(如 1 秒)内计数,超过阈值就拒绝,窗口结束时清零。最简单,但有个致命缺陷——临界点突发。假设限流 100 次/秒,在第 0.9 到 1.0 秒来了 100 个请求,在 1.0 到 1.1 秒又来了 100 个请求,窗口一切换计数清零,这 0.2 秒内实际通过了 200 个请求,远超系统承受。

滑动窗口算法:把固定窗口切成多个小格子(如 1 秒切成 10 个 100 毫秒格子),窗口随时间滑动,统计当前窗口内的请求总数。它缓解了计数器的临界突发问题,因为窗口是滑动的,不会因窗口切换瞬间放过双倍流量。主流的限流组件多基于滑动窗口。

漏桶算法:请求像水一样倒进漏桶,桶以固定速率漏出(处理)。桶满了(超出缓冲容量)就丢弃(拒绝)。它强制输出速率恒定,不管输入怎么波动,输出总是平稳的。适合需要严格平滑流量的场景。

令牌桶算法:系统以固定速率往桶里放令牌,请求来时先拿令牌,拿到了才处理,拿不到(桶空了)就拒绝或等待。桶有容量上限,满了令牌就溢出。和漏桶的差别是:令牌桶允许一定程度的突发——桶里攒了令牌时,瞬间来一批请求都能拿到令牌处理,只要平均速率不超限。这个特性让令牌桶更适合真实业务(业务流量天然有波动),所以它是最常用的限流算法。

算法 原理 优点 缺点 适用场景
计数器 固定窗口计数 简单 临界突发 极简场景
滑动窗口 滑动格子计数 缓解突发 实现稍复杂 主流通用
漏桶 固定速率漏出 输出严格平滑 不允许突发 严格平滑场景
令牌桶 固定速率发令牌 允许突发 实现稍复杂 最常用

2.2 熔断:快速失败防蔓延

熔断器(Circuit Breaker)解决的是“下游慢拖死调用方”的问题。它的灵感来自电路保险丝——电流过大时跳闸保护。

熔断器有三个状态。关闭(Closed):正常状态,请求正常放行,同时统计失败率。打开(Open):失败率超过阈值(如 50%),熔断器打开,所有请求直接快速失败,不再调用下游——给下游恢复的时间,也保护自己不被拖死。半开(Half-Open):打开一段时间后(如 5 秒),熔断器进入半开状态,放少量请求试探下游是否恢复;如果这些请求成功,说明下游恢复了,熔断器关闭恢复正常;如果还失败,重新打开继续等。

熔断的关键参数有三个:失败率阈值(多少比例失败就熔断)、打开持续时间(熔断多久后半开探测)、半开探测请求数(放多少请求试探)。这三个参数要根据下游的故障特征调——下游故障恢复快的,打开时间设短;恢复慢的,设长。

2.3 降级:保核心舍非核心

降级是系统压力过大或部分功能故障时,主动牺牲非核心功能,保住核心功能的手段。它的本质是有取舍的保命。

降级有几种常见策略。返回默认值:某个非核心接口(如推荐)超时,返回一个默认的兜底结果(热门商品列表),不让页面空白。读缓存:数据接口故障,返回缓存的旧数据,虽然不最新但能用。简化逻辑:正常时要查询多个数据源拼装结果,压力时简化成查一个数据源,牺牲丰富度保速度。功能关闭:极端压力下,直接关闭某些功能(评论区、个性化),页面降级成基础版本。

降级的关键是分清核心和非核心。核心功能(下单、支付、登录)任何时候都要保,非核心功能(推荐、评论、个性化)在压力时可以牺牲。这个优先级要提前定好,写进降级预案,别等故障来了才临场决定。

三、工程实践要点

3.1 三板斧配合:纵深防御

限流、熔断、降级单用都不够,要配合形成纵深防御。限流是第一道,控制进入系统的总流量,防过载;熔断是第二道,隔离故障的下游依赖,防蔓延;降级是第三道,在压力或故障时保核心,防雪崩。三层从外到内,各自卡一类风险。

举个完整场景:大促流量涌入,限流先挡住超量的(第一道);某个推荐服务慢了,熔断切断对它的调用(第二道);推荐拿不到数据,降级返回兜底的热门列表(第三道)。用户还能正常浏览下单,只是推荐不那么个性化——这就是三板斧配合的效果,局部故障不拖垮全局。

3.2 参数要按容量测试定

三板斧的参数(限流阈值、熔断条件、降级触发点)不能拍脑袋定,要靠容量测试(压测)定。压测出系统的真实极限(在 SLO 约束下能扛多少 QPS),限流阈值就定在这个极限的 80% 左右留余量;熔断的失败率阈值根据下游的故障特征定;降级的触发点根据系统压力指标定。

⚠️ 常见坑:限流阈值拍脑袋定,定高了形同虚设(系统早挂了限流还没触发),定低了误伤正常流量。必须压测出真实容量,再按容量定阈值。没有压测数据的限流配置,基本等于没配。

3.3 降级要有预案,别临场决定

降级最怕临场慌乱。系统出故障了,谁决定降级、降到什么程度、什么时候恢复,如果没预案,现场讨论半天决定不了,黄金救援时间就过了。所以降级预案要提前写好:哪些功能可降级、触发条件是什么、降级到什么兜底、谁来拍板、怎么恢复。预案要定期演练,确保真出事时大家各司其职。

💡 关键直觉:三板斧是保命装置,不是性能优化。它们的价值是在系统扛不住时主动牺牲局部保全大局,而不是让系统跑得更快。别指望靠限流提速——限流只会让被拒的请求更慢(直接失败)。理解这一点,你才不会对三板斧的作用抱错期望。

踩坑与要点

  • 限流四算法:计数器(临界突发)、滑动窗口(主流)、漏桶(严格平滑)、令牌桶(允许突发,最常用)。
  • 令牌桶 vs 漏桶:令牌桶允许突发,适合真实业务的波动流量;漏桶强制平滑,不允许突发。
  • 熔断三状态:关闭(正常统计)、打开(快速失败)、半开(探测恢复),防下游慢拖死调用方。
  • 熔断参数:失败率阈值、打开持续时间、半开探测数,按下游故障特征调。
  • 降级策略:返回默认值、读缓存、简化逻辑、功能关闭,按核心优先级保命。
  • 纵深防御:限流防过载、熔断防蔓延、降级防雪崩,三层配合。
  • 参数靠压测:限流阈值按真实容量的 80% 定,降级要有预案定期演练。

下一章我们钻进应用层,看怎么把应用做成无状态、能弹性伸缩、能异步削峰的。

参数整定的实战手感

限流熔断的参数整定没有公式,但有一些可以传承的手感。限流阈值不能直接用压测峰值——压测环境与生产的差异(数据量、缓存命中率、长尾请求分布)会让压测值偏乐观,工程惯例是在压测峰值上打七到八折起步,观察一周再上调。熔断的错误率窗口要和下游的恢复节奏匹配:窗口太短,偶发抖动就熔断,恢复期反而放大故障;窗口太长,熔断形同虚设。经验起点是一分钟窗口加百分之五十错误率,配合半开状态的并发试探数限制在一到两个。降级开关要分级:一级降级砍推荐和评论文本,二级砍图片质量,三级砍到静态页面——每一级都有明确的触发条件和恢复条件,写进预案并演练过,而不是出事时现场决定砍什么。

还有一个反直觉的经验:恢复比触发更难。降级容易恢复难——流量回落到阈值下就直接恢复的话,尚未热身的缓存会被瞬时打死,形成二次故障。正确做法是恢复也按百分比爬坡,配合预热脚本先让缓存升温再放量。限流的恢复同理,排队队列的排空速度要限速。把"恢复策略"当作和"触发策略"同等重要的设计项,是经历过二次故障的团队才会有的肌肉记忆,希望你在这里提前建立它。

还有一个容易被轻视的工程细节:限流熔断的配置要有版本管理和灰度能力。防护参数改动直接全量生效的风险不亚于业务变更——阈值调高百分之十,可能就是压垮下游的最后一根稻草。把防护配置当成代码管理:评审、变更记录、灰度生效、可回滚,四样齐备才允许上线。见过太多事故的根因就是某人在管理台手滑改了个数字,而没有任何留痕和灰度缓冲。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U