那次事故到现在我都记得很清楚。凌晨两点,大促压测刚跑起来十分钟,下单接口的TP99就从50ms一路飙到3秒,数据库连接池被打满,紧接着商品详情页、购物车、订单查询全开始超时。群里的第一反应特别统一:赶紧限流、熔断、降级。但真到动手的时候,三个人给出三个方案——有人要在网关层限制QPS,有人要立刻熔断对库存系统的调用,还有人要把营销推荐模块直接关掉。争论了十分钟才发现,大家说的根本不是同一件事。
“限流、熔断、降级”这三板斧,几乎每个做后端的人都挂在嘴边,但真正能把它们拆开讲清楚的人不多。它们都属于高并发系统保护的范畴,却分别解决不同环节的问题:一个管入口流量,一个管故障止损,一个管资源取舍。用错了,轻则保护无效,重则误伤正常用户。这篇就基于我自己的线上经验,把三者彻底掰开揉碎讲透,包含算法原理、参数设计、框架落地和踩坑记录。
1. 一次线上故障教会我的:保护三板斧各管一段
1.1 事故现场:不是加机器就能解决的
先还原一下当时的情况。我们是一个典型的微服务架构,入口是Nginx和网关,往下是订单、库存、营销、用户等一堆服务。压测把流量打到正常峰值的5倍以后,最先扛不住的是数据库——连接数耗尽,所有请求都在等连接。数据库慢下来,调用它的服务线程就开始堆积,线程一堆积,服务的健康检查开始超时,服务发现里开始出现不健康的实例。如果没有人为干预,这个链路会沿着调用关系向上传递,最终入口也拒绝服务。
当时有个同学说了一句很有代表性的话:“扛不住就加机器呗。”但压测期间加机器根本来不及,而且数据库是单点,加应用实例救不了数据库连接池。真正的问题是:系统的承载能力是有上限的,而流量是瞬时的,必须有一种机制在系统被压垮之前主动放弃一部分请求或功能。
1.2 团队里的三种声音与认知偏差
压测现场,团队内部的讨论很有意思,基本代表了大多数人对这三板斧的误解。
第一种声音:“网关把QPS限到2万,超过的直接返回。”这是限流思维,解决的是入口流量过大的问题。但它不解决下游已经故障的情况——如果库存服务已经挂了,无论入口限多少流量,调用库存的请求依然会失败。
第二种声音:“把库存服务的调用熔断掉,快速失败。”这是熔断思维,解决的是调用方被故障下游拖死的问题。但如果库存服务只是慢,还没到熔断阈值呢?或者流量还没大到触发熔断呢?
第三种声音:“把营销推荐关掉,先保住交易主链路。”这是降级思维,解决的是系统资源不够时怎么取舍的问题。但如果入口流量不减,光靠降级也扛不住全量请求。
三种方案听起来都对,但作用的位置、触发条件、保护对象全都不一样。把它们当成“反正都是保护系统,随便上一个就行”,这正是线上事故扩大的常见原因。
1.3 复盘得出的关键认知
事后我们复盘,发现这三者其实是一条完整的防御链——限流在入口放弃流量,熔断在调用层放弃故障请求,降级在业务层放弃非核心功能。它们相互补充,但绝不能互相替代。后面几节,我逐个把它们的原理、算法、参数和落地方式讲清楚。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 限流:在入口做减法,保护的是“系统不被打爆”
2.1 限流到底在限制什么
限流的本质是:在单位时间内,只允许一定数量的请求进入系统,多出来的请求直接拒绝、排队或者走降级策略。它是一道防盗门,不管来的人是谁,只要超过了门禁容量,就先挡在外面。
关键点是,限流不需要关心下游是否健康。哪怕下游一切正常,只要流量超过系统承载力,限流就该工作。所以限流保护的是整体系统的“输入边界”,是一种主动防御。
限流限的指标常见有两种:一是QPS(每秒请求数),二是并发数。QPS限流适合接口类场景,控制每秒钟放进来多少请求;并发限流控制的是同时处理的请求数,比如数据库连接池是100个连接,那就限制同时最多100个请求在查数据库。我在项目里通常两个都配:网关按QPS限,服务内部对数据库操作按并发数限。
2.2 四种常见限流算法:没有银弹,只有取舍
限流算法网上资料一大堆,但真正到了选型时,要考虑的是业务特点。我直接用一张表对比四种主流算法:
| 算法 | 核心思路 | 优点 | 缺点 | 适用场景 |
|------|-----
