Yihui’s Blog

限流与限流算法

日期:2026-07-11
标签:#面试 #八股 #后端 #系统设计 #场景题

一句话答案

限流是在资源容量边界前拒绝或延迟部分请求,常见算法有固定窗口、滑动窗口、漏桶和令牌桶,其中令牌桶最适合允许一定突发的通用接口限流。

算法对比

算法特点问题/适用场景
固定窗口实现简单,按窗口计数窗口边界可能瞬间通过双倍流量
滑动日志记录每次请求时间,精确内存成本高
滑动窗口计数多小格近似统计精度与成本可调
漏桶恒定速率流出,流量平滑对突发不友好,适合保护稳定下游
令牌桶恒速产令牌,可积累后应对突发需设速率和桶容量

面试口语版

限流前先根据压测确定系统安全容量,再选择作用范围:单机可用内存令牌桶,分布式可由网关结合 Redis Lua 做原子限流。维度可以是接口、用户、租户、IP 或业务优先级。超过阈值后不只是返回 429,还可以排队、降级、使用缓存或丢弃低优先级任务。限流必须配合监控,否则阈值错误会把正常流量误杀。

关键细节

  • 分布式限流要权衡强一致和性能,本地限流配合集中配额下发常更稳健。
  • 限流放在越靠前的位置,节省的后端资源越多;核心服务仍要做自保护。
  • 重试请求也消耗容量,客户端应遵循 Retry-After 并指数退避。

面试官追问

  1. Redis 如何原子实现令牌桶?
  2. 网关宕机或 Redis 不可用时 fail-open 还是 fail-close?
  3. 如何设计动态限流?

面试官追问参考答案

1. Redis 如何原子实现令牌桶?

Key 保存当前令牌数和上次补充时间。Lua 脚本根据当前时间计算应补令牌数,取不超过桶容量的值,再判断是否足够消费并更新状态,整个过程单 Key 原子执行;还要设置过期时间,避免长期不用的桶占内存。

2. 网关宕机或 Redis 不可用时 fail-open 还是 fail-close?

取决于业务风险。登录浏览等低风险接口可 fail-open 并启用单机保底限流,保证可用性;支付、资金、库存等高风险接口宜 fail-close 或进入严格降级,避免突破硬约束。策略要按接口分级,不能全局固定。

3. 如何设计动态限流?

以压测容量为静态上限,再根据 CPU、延迟、错误率、线程池排队和下游健康动态调整配额。可用 AIMD 或自适应并发限制,下降要快速、恢复要缓慢并设上下界和迟滞,配置通过控制面下发,数据面保留本地兜底。

维护与整理 · Yihui在 GitHub 上编辑

继续阅读

浏览全部文章