API 限流是每个后端系统都需要的基础能力。面试中常让你设计一个限流器。
需求
- 限制每个用户/API Key 的请求频率
- 比如:每分钟最多 100 次请求
- 超过限制返回 429 Too Many Requests
- 需要支持分布式部署
常见算法
固定窗口
把时间分成固定窗口(比如每分钟),每个窗口独立计数。简单但有问题——窗口边界处可以发送 2 倍的请求(上分钟的最后 1 秒 + 这分钟的第 1 秒)。
滑动窗口日志
记录每次请求的时间戳,查询最近 N 秒内的请求数。精确但内存占用大。
滑动窗口计数器
结合前一个窗口的请求数做加权计算。Redis 的 ZSET 可以实现。
令牌桶(最常用)
以固定速率往桶里放令牌(比如每秒 10 个)。请求来时取一个令牌——取到就通过,取不到就拒绝。桶有容量上限,允许一定的突发流量。
实现
// 用 Redis 实现令牌桶
String key = "rate_limit:" + userId;
long now = System.currentTimeMillis();
long tokens = redis.incr(key);
redis.expire(key, 60); // 窗口 60 秒
if (tokens > 100) return 429;
// 处理请求...
分布式限流
多节点部署时,需要共享计数器——用 Redis 解决。但 Redis 本身也可能成为瓶颈。解决方案: - 本地限流 + 全局限流双层方案 - 本地做粗粒度限流(比如单节点 1000/s),全局限严格(比如总体 5000/s)
面试要点
必须提到令牌桶算法和滑动窗口的区别。能说出分布式限流的双层方案是加分项。
评论
评论已关闭。