什么是限流?分布式系统为什么需要流量控制?
简化版
限流就是在流量超过系统承载能力或业务规则时,主动限制一部分请求,避免下游被打垮。分布式系统做流量控制的核心目标不是“拒绝用户”,而是保护核心链路,让系统在高峰、突刺、攻击和依赖异常时仍能稳定服务。
详细版
限流主要解决几类问题:
- 防止突发流量压垮服务、数据库、缓存、消息队列;
- 防止单个用户、租户、接口或来源占满共享资源;
- 保护下游依赖,避免超时堆积引发雪崩;
- 在大促、秒杀、热点事件中削峰填谷;
- 配合熔断、降级、排队和异步化,保障核心链路。
限流可以按维度划分:全局限流、接口限流、用户限流、IP 限流、租户限流、资源限流、下游依赖限流。常见算法有固定窗口、滑动窗口、漏桶、令牌桶、并发数限制、排队限速等。
面试回答时要强调:限流不是孤立组件,而是稳定性体系的一部分。限流阈值要来自容量评估和压测,拒绝策略要有业务语义,监控要能看清被限流量、通过量、延迟和下游健康状态。
完整版教学
一、限流的本质是承认系统容量有上限
任何系统都有容量上限。应用线程池有上限,数据库连接池有上限,磁盘 IO 有上限,缓存带宽有上限,下游接口也有上限。流量超过上限后,如果系统不主动控制,请求不会凭空消失,而是会排队、超时、重试、占满线程和连接,最终把整个链路拖垮。
限流的价值就在于把“无序崩溃”变成“有序拒绝”。有序拒绝虽然会让一部分请求失败,但能保护剩余请求成功,也能保护核心链路继续运行。比如秒杀时只允许系统能处理的请求进入交易链路,其他请求快速返回排队、售罄或稍后再试,比让所有请求冲进数据库导致全站不可用要好得多。
因此限流不是用户体验的敌人。没有限流时,用户可能看到长时间转圈、最终超时、重复下单、支付状态混乱;有限流时,至少系统能给出明确反馈,并保住真正能成交的请求。
二、限流要先明确保护对象
很多同学把限流理解成“每秒最多多少请求”,但限流阈值不能凭空设。先要明确你要保护什么:保护某个接口的线程池,保护数据库写入能力,保护 Redis 热点 Key,保护第三方短信接口额度,还是保护某个租户不能影响其他租户。
保护对象不同,限流维度也不同。保护数据库写入,可能按接口全局 QPS 限流;保护租户公平性,可能按租户 ID 限流;保护登录安全,可能按用户、IP、设备指纹限流;保护下游支付渠道,可能按渠道维度限流。
如果维度选错,限流会失效。比如只做全局限流,某个大客户可能吃掉所有额度,普通用户仍然不可用;只按 IP 限流,移动网络 NAT 后大量真实用户共用出口 IP,可能误伤。
三、限流、熔断、降级的边界不同
限流关注的是“流量是否超过承载能力”,通常在流量进入系统或进入某个资源前做控制。熔断关注的是“下游是否异常”,当错误率或超时达到阈值时,短时间停止调用下游。降级关注的是“功能是否可以简化”,用默认值、缓存、异步或关闭非核心功能保住主流程。
三者经常配合。比如商品详情页推荐服务慢了,先通过超时控制避免线程长期阻塞;错误率持续升高后熔断推荐服务;页面用默认推荐位降级;如果详情页整体流量过高,再对接口做限流。它们解决的问题不同,但目标都是防止局部问题扩散。
面试里如果能把这几个概念讲清,就不会把所有稳定性手段都混成“限流”。
四、阈值来自容量评估,而不是拍脑袋
限流阈值最好来自压测和容量模型。假设订单创建接口压测发现单实例稳定处理 300 QPS,部署 10 个实例,考虑数据库、缓存、下游支付等瓶颈后,整体安全容量可能不是 3000 QPS,而是 1800 QPS。因为最短板资源可能在数据库或下游,不在应用实例。
阈值还要留安全水位。系统在 80% 负载下可能很稳,在 95% 负载下 P99 延迟急剧上升。限流阈值应该保护系统运行在可控区间,而不是等到资源打满才动作。
动态阈值也很常见。当下游延迟上升、错误率升高、线程池队列变长时,可以自动降低放行速率;当系统恢复后逐步放开。这比固定阈值更适合复杂环境,但实现难度和误判风险也更高。
五、拒绝策略必须有业务语义
限流后的请求怎么处理,不能只有一个冷冰冰的 500。常见策略包括返回 429 Too Many Requests、提示稍后重试、排队等待、降级展示、进入异步任务、返回缓存结果、直接售罄。不同业务要选不同策略。
对于开放 API,返回 429 并带 Retry-After 可以让客户端按约定退避。对于秒杀,超过系统承载量的请求可以直接返回活动火爆或排队中。对于后台导出,可以改成异步任务。对于查询接口,可以返回稍旧缓存。
拒绝策略还要避免诱发更大流量。如果页面提示“请立即重试”,用户和客户端会疯狂刷新,限流反而引发重试风暴。更好的做法是明确退避时间、按钮置灰、客户端指数退避或排队通知。
六、限流要能观测和运营
上线限流后,必须监控通过量、拒绝量、排队量、等待时间、限流维度分布、下游错误率、系统资源水位。否则你只知道用户被挡了,却不知道挡得是否合理。
运营和客服也要能理解限流状态。比如大促期间某地区请求被限流,是攻击、黄牛、真实高峰还是容量不足?某个租户被限流,是超过合同额度还是系统误判?这些都需要指标和日志支撑。
限流规则也要可配置、可灰度、可回滚。事故中临时改代码发布限流,是很危险的做法。成熟系统通常通过配置中心或流量治理平台动态调整规则。
七、面试追问里的关键取舍
面试官常问“限流放在网关还是服务内”。网关限流靠近入口,能尽早挡住流量,适合 IP、用户、租户、接口级粗粒度限流;服务内限流更了解业务状态,适合按库存、订单、下游依赖、线程池等细粒度限流。两者经常同时存在。
还会问“单机限流和分布式限流怎么选”。单机限流性能好、简单,但多实例下只能限制单实例流量;分布式限流能控制全局额度,但依赖 Redis、限流服务或网关集群,性能和可用性要仔细设计。核心原则是:能本地解决的不要强行全局,确实需要全局公平或总量保护时再做分布式限流。
八、常见误区与追问
这道题要紧扣「限流」本身回答,不能把它混成泛泛的流量控制套话。面试官通常不是只听定义,而是看你能不能把适用场景、关键流程、失败边界和工程取舍串起来,尤其要说明限流位置、算法窗口、阈值来源、拒绝策略、退避降级和观测指标。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心结论 | 限流是在系统承载能力前设置阈值,超过阈值时排队、拒绝或降级,保护核心服务不被流量打垮 | 不要停在名词解释 |
| 流程机制 | 评估系统容量 -> 设置限流维度 -> 请求进入算法 -> 超过阈值触发策略 -> 返回友好失败 -> 根据指标调参 | 要说清触发点、状态变化、确认点和失败兜底 |
| 工程取舍 | 服务稳定容量 3000 QPS,就不应让 10000 QPS 直接进入数据库连接池 | 限流保护系统稳定性,但会牺牲一部分请求成功率或响应实时性 |
限流 面试拆解:
1. 评估系统容量
2. 设置限流维度
3. 请求进入算法
4. 超过阈值触发策略
5. 返回友好失败
6. 根据指标调参
记忆钩子:先给结论,再拆流程,再讲数字例子和失败边界;回答「限流」时要围绕题目问法收束,不要把相邻概念堆成一段没有重点的名词清单。
- 误区:限流就是简单拒绝请求。 合格答案要区分放行、排队、快速失败、降级、退避和熔断,而不是只说“挡住流量”。
- 误区:全局平均流量低就没有风险。 热点 key、单实例、单下游资源仍可能先被打满,所以要看局部水位。
- 误区:限流阈值可以拍脑袋配置。 阈值要来自压测容量、依赖水位、错误率、P99 延迟和业务优先级。
- 追问:限流应该放在哪里? 入口网关、服务内部、客户端和下游资源侧可以分层配置,分别保护不同边界。
- 追问:触发限流后怎么处理? 核心写请求可排队,非核心读请求可降级,用户侧要给明确失败或稍后重试。
- 追问:如何验证流控策略有效? 看 QPS、并发、延迟、拒绝率、队列长度、下游错误率和恢复时间。
九、加强记忆
限流的核心不是拒绝请求,而是在容量有限时保护系统有序运行。先确定保护对象,再选择限流维度和算法,阈值来自压测和容量评估,拒绝策略要符合业务语义,监控和动态配置必须跟上。能讲清这些,限流就不再是一个算法名词,而是一套稳定性设计。