← 返回题目列表

Node.js 接口限流通常怎么设计?

中等 第 20 / 27 题 更新于 2026/07/29
Node.js限流RedisAPI

简化版

Node.js 接口限流通常按 IP、用户、接口或租户维度限制请求频率,常见算法有固定窗口、滑动窗口、漏桶和令牌桶。单机可用内存计数,分布式场景通常用 Redis 原子计数或 Lua 脚本,并配合网关限流。

详细版

限流不是只防攻击,也用于保护下游和稳定体验。 简单固定窗口示例:

const key = `rate:${ip}:${Math.floor(Date.now() / 60_000)}`
const count = await redis.incr(key)
await redis.expire(key, 60)
if (count > 100) {
  throw new Error('Too Many Requests')
}

真实系统要考虑维度、算法、分布式一致性、误伤、返回码、重试提示和监控。常见响应是 HTTP 429,并带上 Retry-After

完整版教学

一、限流的目标是保护系统边界

没有限流时,一个异常用户、爬虫或前端 bug 就可能打满服务。 Node.js 本身事件循环轻,但下游数据库、Redis、第三方接口都有容量上限。 限流是在入口处把风险挡住。

请求流量
-> 限流
-> 鉴权
-> 业务
-> DB / Redis / 第三方接口

假设登录接口每秒正常 50 次,突然被刷到每秒 5000 次。 如果不限制,密码校验、数据库查询和短信服务都会被拖垮。

二、限流维度决定公平性

只按 IP 限流很容易误伤公司 NAT 或校园网用户。 只按用户限流又挡不住未登录攻击。 工程里常组合多个维度:IP、用户 ID、接口、租户、设备和 API Key。

维度适合场景风险
IP未登录接口NAT 误伤
用户 ID登录后接口账号被盗时仍要辅助 IP
API Key开放平台Key 泄漏风险
接口路径保护重接口规则维护成本

例如发送验证码可以按手机号、IP、设备三重限制。 这样比单一维度更能防刷,也更少误伤正常用户。

三、固定窗口简单但边界突刺明显

固定窗口按时间段计数,例如每分钟最多 100 次。 实现简单,Redis INCR + EXPIRE 就能做。 问题是窗口边界可能放过突刺。

12:00:59 允许 100 次
12:01:00 又允许 100 次
2 秒内实际通过 200 次

如果接口对瞬时流量敏感,固定窗口不够平滑。 但对于管理后台、低风险接口,它仍然是性价比很高的方案。

四、滑动窗口和令牌桶更平滑

滑动窗口按最近一段时间统计,更准确但存储和计算成本更高。 令牌桶按固定速率生成令牌,请求拿到令牌才通过,允许一定突发。 漏桶则更强调固定速率流出。

令牌桶:
桶容量 100
每秒生成 10 个令牌
请求消耗 1 个令牌
桶空则限流
算法平滑度实现成本适合场景
固定窗口简单接口
滑动窗口中高精确限制
令牌桶中高允许突发
漏桶平滑输出

面试回答不需要把所有算法数学化。 关键是能讲出取舍和业务适配。

五、分布式限流要保证原子性

多实例 Node 服务不能用单机内存计数做全局限流。 同一个用户请求可能打到不同实例。 通常用 Redis 做共享计数,并用 Lua 脚本保证检查和更新原子。

local current = redis.call('INCR', KEYS[1])
if current == 1 then
  redis.call('EXPIRE', KEYS[1], ARGV[1])
end
return current

如果 INCR 成功但 EXPIRE 失败,key 可能永久存在。 Lua 能把多步操作打包成原子逻辑,减少边界 bug。

六、限流响应要对客户端友好

被限流时通常返回 429 Too Many Requests。 响应体要给出明确错误码,响应头可加 Retry-After。 同时日志和监控要记录命中的规则、维度和当前计数。

记忆钩子:限流不是拒绝用户,是保护系统别被浪拍翻。

限流也要能灰度和动态调整。 规则太紧会误伤,太松又保护不了下游。

七、常见误区与追问

  • 误区:限流只按 IP 做就够了。 NAT、代理和未登录攻击会让单一 IP 维度不可靠,应组合维度。
  • 误区:单机内存限流适合所有部署。 多实例环境下内存计数不共享,全局限流通常要 Redis 或网关。
  • 误区:固定窗口没有缺点。 窗口边界会产生突刺,可能短时间通过两倍流量。
  • 追问:为什么用 Lua? 保证检查、计数、过期等多步 Redis 操作的原子性。
  • 追问:限流返回什么状态码? 常用 429,并可携带 Retry-After 提示重试时间。
  • 追问:网关限流和应用限流怎么分工? 网关挡通用流量,应用按业务维度做精细规则。

八、加强记忆

限流题按“维度、算法、分布式、响应”记。维度决定公平性,算法决定平滑度,Redis/Lua 保证多实例一致,429 和监控保证可运营。别只写一个计数器,那只是入门版。