限流算法有哪些?固定窗口、滑动窗口、令牌桶、漏桶怎么选?
🧑💻 面试官:接口限流用什么算法?
🙋♂️ 我:令牌桶最好,能解决所有突发请求。
🧑💻 面试官:允许突发和要求平滑输出,是一样的目标吗?
🙋♂️ 我:不一样,漏桶更强调平滑。
🧑💻 面试官:十台实例各限一百,总共还是一百吗?慢请求占住资源又只看 QPS 够不够?
先规定限制谁、限制什么、允许多少突发,再谈算法;本地额度不会自动变成全局额度。
面试速答(60 秒版)
固定窗口按时间段计数,简单但边界附近可能集中放行;滑动窗口观察最近一段时间,可以采用日志或分段计数,精度和成本不同。
令牌桶以设定速率补充令牌,容量限制可积累的突发额度;漏桶的典型排队整形模型以受控速率输出,但不同产品的计量和排队行为要看实现。
多实例限流需要共享原子状态、额度分配或明确接受近似,不然每个实例各限一百不等于全局一百。还要区分速率限制和并发限制,长请求可能在低 QPS 下占满资源。
超限时约定拒绝、等待或降级,重试遵守退避,限流状态存储故障时也要明确策略。

知识点详解:算法之外,额度边界更重要
固定窗口的短板,发生在切换附近
假设每秒最多十次,计数在整秒清零。在前一秒末尾十次、后一秒开头十次都被允许,极短时间就可能集中出现二十次。
这不违反各自固定窗口的规则,却可能超出你希望的任意最近一秒十次。需求不同,正确答案也不同。
滑动日志记录每次时间,分段计数用更少状态近似窗口;不要把所有滑动窗口都说成精确记录所有请求。
令牌桶允许积累,漏桶强调输出形态
假设桶容量二十,每秒补十份令牌,空闲后可以立即消耗积累的额度。因此平均补充速率不是任意极短区间的硬上限。
典型漏桶整形通过队列控制发出节奏,队列满时拒绝或丢弃。但产品也可能采用漏桶计量并允许不同的延迟、突发配置,具体不能只看名字。
例如 Nginx limit_req 的 burst、delay、nodelay 会影响请求实际等待与放行方式。不能只背“漏桶必定所有请求匀速排队”。
多实例先定义额度属于谁
假设十台服务,每台本地允许一百请求。总放行量可能接近一千,而且分配不均会让某些用户受到额外限制。
共享存储需要原子完成检查与扣减,并评估访问延迟和故障依赖;提前分配本地额度减少协调,却要处理浪费和短时超发边界。
按用户、租户、接口或全站限制也不同。只按 IP 可能把共享出口的用户合在一起,可信身份与代理地址处理要先明确。
QPS 不足以保护慢资源
假设任务平均要运行十秒,持续每秒十个请求,系统仍可能积累很多在途工作。并发上限或资源许可比只看速率更直接。
排队需要容量和等待时限,否则拒绝变成占住内存等待。429 等响应和 Retry-After 可以帮助客户端理解,但服务默认状态码还要看配置。
测试覆盖窗口边界、突发、多实例、慢请求和状态服务失效。失效时放行还是拒绝,按资源风险定,不能作为万能固定答案。
本题机制参考:ASP.NET Core 限流说明、Nginx limit_req、Azure 限流模式。

面试官继续追问
令牌桶能保证完全没有突发吗?
不能,它允许容量范围内积累额度。需要明确容量与补充速率。
限流就是防 DDoS 吗?
不是完整防护。网络容量、分布式攻击和边缘防护等仍要评估。
固定窗口更简单,就一定不合适吗?
不是。需求允许窗口边界突发时,它可以是合理的低成本选择。
面试速记卡
- 需求:对象、速率/并发、突发与超限行为。
- 固定窗口:简单,注意窗口边界。
- 滑动窗口:精度与状态成本取舍。
- 令牌桶:补充速率+容量;漏桶行为看实现。
- 多实例:共享或分配额度,不能只叠本地配置。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →