概述
固定窗口限流在边界处允许两倍突发,且每实例各算一份会放大限额。滑动窗口或令牌桶配合共享状态,可让限额平滑且全局一致,代价是每次请求多一次共享存储往返。
关键步骤
- 选择滑动窗口或令牌桶,而非固定窗口。
- 以客户端标识与路由为键,在共享存储中保存计数或令牌。
- 用 Lua 脚本或原子操作读写计数。
- 超限时返回 429 与 Retry-After 及限额头。
验证
- 边界处不会出现两倍突发。
- 多实例共享同一限额。
- 并发请求不会超出限额。
- 客户端能按 Retry-After 退避。
注意事项
- 共享存储限流每请求增加一次往返,自身可能成为瓶颈。
- 分区下分布式限流是近似值,需明确其失败模式。
适用范围
本条目围绕「实现滑动窗口限流」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。
const allowed = await redis.eval(TOKEN_BUCKET_LUA, 1, `rl:${clientId}`, now, rate, capacity);
if (!allowed) {
res.setHeader('Retry-After', '1');
return res.status(429).json({ error: { code: 'rate_limited' } });
}