一、限流概述:为什么需要限流?
大家好,我是这次课程的主讲。在正式开始之前,我想先问一个问题:你负责的 API 有没有被突发流量打垮过?
我遇到过。几年前的一个双十一,我们团队负责的订单查询接口,在零点瞬间涌入平时 50 倍的请求量。结果呢?数据库连接池爆了,整个服务集群雪崩,连带着下游的库存、支付系统一起挂了。那次事故,我们花了整整 4 个小时才恢复。
事后复盘,核心原因就一个:没有限流。
1.1 为什么需要限流?
说白了,限流就是给系统装一个「水龙头」。你想想看,水管再粗,也有最大承载量。如果上游水库突然开闸放水,下游的管道、水泵、水龙头都会被冲坏。
在分布式系统里,这个道理一模一样。你的服务器、数据库、缓存、消息队列,每个组件都有它的处理上限。当请求量超过这个上限,系统就会开始排队、超时、崩溃。
我总结了一下,限流要解决的核心问题有三个:
- 保护自身:防止单机资源(CPU、内存、连接数)被耗尽
- 保护下游:避免对数据库、第三方 API 等依赖服务造成冲击
- 公平服务:确保高优先级用户或核心业务不被低优先级流量挤垮
核心观点:限流不是限制用户,而是保护用户。一个被限流但能正常返回提示的 API,远比一个直接超时或返回 500 的 API 更友好。
1.2 限流与熔断、降级的关系
很多同学容易把限流、熔断、降级这三个概念搞混。我刚开始做架构设计时也犯过这个错。其实它们是一套组合拳,各有各的职责。
来看这张图,你就明白了:
我来给你拆解一下这三者的区别:
| 维度 | 限流 | 熔断 | 降级 |
|---|---|---|---|
| 触发条件 | 请求速率超过阈值 | 错误率/延迟超过阈值 | 资源不足或熔断触发 |
| 动作 | 拒绝多余请求 | 断开调用链路 | 返回降级结果 |
| 恢复方式 | 流量下降后自动恢复 | 半开探测后恢复 | 手动或自动恢复 |
| 典型场景 | 秒杀、抢购 | 数据库连接超时 | 推荐服务不可用 |
我的经验:在实际项目中,我习惯把限流放在最外层(网关层),熔断放在服务调用层(RPC 客户端),降级放在业务逻辑层。这样分层治理,每个层各司其职,互不干扰。
1.3 限流的核心目标
搞清楚了为什么需要限流,以及它和熔断、降级的关系,我们再来看看限流本身要达成哪些目标。我个人把它归纳为四个核心目标:
- 精准控制:能够精确地限制每秒/每分钟的请求量,误差控制在 5% 以内
- 低延迟:限流判断本身不能成为性能瓶颈,通常要求单次判断耗时 < 1ms
- 公平性:不能让某个用户或某个 IP 把整个系统的配额全部占完
- 可观测:限流了多少请求、被限流的请求来自哪里,这些数据必须能监控到
嗯,这里要注意一点。很多团队把限流做成了「黑盒」——限流了,但没人知道限了多少、为什么限。我曾经接手过一个项目,线上限流配置是半年前写的,阈值早就过时了,结果正常业务流量都被限了,用户投诉一大堆。
避坑指南:我曾经见过一个团队,限流阈值设得太低,导致大促期间 80% 的请求被拒绝。更糟糕的是,他们没做限流告警,直到业务方反馈用户下不了单才发现。所以,限流一定要配合监控和告警一起做。
1.4 什么时候不该限流?
说了这么多限流的好处,我也得泼点冷水。限流不是万能的,有些场景下盲目限流反而会坏事:
- 读多写少的查询接口:如果查询可以走缓存,优先优化缓存,而不是限流
- 异步处理的任务:消息队列本身就具备削峰填谷的能力,不需要额外限流
- 内部管理接口:运维后台、配置中心等低频接口,限流反而会影响正常运维
说白了,限流是最后一道防线,不是第一选择。在考虑限流之前,先问问自己:能不能加缓存?能不能异步化?能不能扩容?这些手段都比限流更优雅。
1.5 本章小结
这一章我们聊了限流的基本概念。核心就三件事:
- 限流是为了保护系统不被突发流量冲垮
- 限流、熔断、降级是三个不同的策略,要配合使用
- 限流的核心目标是精准、低延迟、公平、可观测