请求速率限制
类型
server hook
速率限制,在一定时间内最大只能发起 N 个请求,例如以下场景。
- node 作为中间层请求下游服务时,在资源消耗严重的 api 下,通过 ip 进行限制以免消耗下游服务器资源
- 防止密码暴力破解,下游服务器连续多次抛出登录错误时,通过 ip 或用户名进行限制
- 作为 sendCaptcha 的发送限制,防止用户频繁发送验证码
特性
- 在一定时间内限制请求次数;
- 支持集群,单服务器多线程或者多服务器;
- 支持请求间隔时间;
- 可达速率限制后,延长重置时间,例如登录锁定;
- 奖励机制、惩罚机 制、重置机制;
用法
基本用法
创建一个可复用的rateLimit函数(server hook),并使用它包裹 method 实例并返回请求限制的 method 实例。
const rateLimit = createRateLimiter({
/**
* 点数重置的时间,单位ms
* @default 4000
*/
duration: 60 * 1000,
/**
* duration内可消耗的最大数量
* @default 4
*/
points: 4,
/**
* 命名空间,多个rateLimit使用相同存储器时可防止冲突
*/
keyPrefix: 'user-rate-limit',
/**
* 锁定时长,单位ms,表示当到达速率限制后,将延长[blockDuration]ms,例如1小时内密码错误5次,则锁定24小时,这个24小时就是此参数
*/
blockDuration: 24 * 60 * 60 * 1000,
/**
* 延迟操作将在持续时间内均匀执行
* @default false
*/
execEvenly: true,
/**
* 最小延迟时间(以毫秒为单位)
* @default duration/points
*/
execEvenlyMinDelayMs: 60 * 1000 / 4
});
// 在请求中使用rateLimit
const app.get('/api/user', (req, res) => {
const userResult = await rateLimit(alova.Get('/api/user?id=' + req.query.id), {
// 通过key来追踪不同用户的请求限制
key: req.query.id
});
// ...
});
注意
当请求被限制时,将会抛出错误,而不是等待请求。