推荐答案
// www.javascriptcn.com code example
const fastify = require('fastify')();
const rateLimit = require('fastify-rate-limit');
// 注册 fastify-rate-limit 插件
fastify.register(rateLimit, {
max: 100, // 每个时间窗口内的最大请求数
timeWindow: '1 minute', // 时间窗口长度
cache: 10000, // 缓存大小
whitelist: ['127.0.0.1'], // 白名单 IP
redis: new Redis({ host: '127.0.0.1' }), // 使用 Redis 存储请求计数
skipOnError: true, // 在发生错误时跳过限流
keyGenerator: (req) => req.headers['x-forwarded-for'] || req.ip, // 自定义生成限流 key
errorResponseBuilder: (req, context) => ({
statusCode: 429,
error: 'Too Many Requests',
message: `Rate limit exceeded, retry in ${context.after}`
}) // 自定义错误响应
});
// 启动服务器
fastify.listen(3000, (err) => {
if (err) throw err;
console.log('Server is running on http://localhost:3000');
});本题详细解读
1. 插件的作用
fastify-rate-limit 是一个用于限制请求频率的 Fastify 插件。它可以帮助你防止恶意用户或脚本对服务器进行过多的请求,从而保护服务器资源。
2. 配置选项
- max: 每个时间窗口内允许的最大请求数。超过这个数量的请求将被拒绝。
- timeWindow: 时间窗口的长度,可以是字符串(如
'1 minute')或毫秒数。 - cache: 缓存大小,用于存储请求计数。默认值为 5000。
- whitelist: 白名单 IP 地址数组,这些 IP 地址不受限流规则的限制。
- redis: 使用 Redis 存储请求计数,适用于分布式环境。
- skipOnError: 当发生错误时是否跳过限流。默认值为
false。 - keyGenerator: 自定义生成限流 key 的函数。默认使用请求的 IP 地址。
- errorResponseBuilder: 自定义错误响应的函数。默认返回 429 状态码和错误信息。
3. 使用场景
- API 限流: 防止 API 被滥用,保护后端服务。
- 防止 DDoS 攻击: 通过限制请求频率,减少恶意请求对服务器的影响。
- 资源保护: 限制对某些高负载资源的访问频率,确保服务的稳定性。
4. 注意事项
- 分布式环境: 在分布式环境中,建议使用 Redis 存储请求计数,以确保限流规则的一致性。
- 性能影响: 限流插件会增加一定的性能开销,特别是在高并发场景下,需要合理配置
cache和timeWindow参数。 - 错误处理: 如果限流插件发生错误(如 Redis 连接失败),可以通过
skipOnError参数决定是否继续处理请求。