如何为MongoDB Function Endpoint防垃圾请求并实现请求限流?
MongoDB函数流量限制与垃圾请求防范方案
一、流量限制实现
1. 利用Atlas内置速率限制
直接在MongoDB Atlas的函数配置界面中找到速率限制选项,设置单IP或全局的请求频次上限(比如每分钟10次),超过阈值的请求会被自动拦截并返回429状态码,无需修改代码。
2. 自定义IP限流逻辑
如果需要更灵活的控制,可以通过额外集合记录IP请求频次,实现细粒度限流:
- 创建
rate_limits集合,用于存储IP、请求次数、时间戳 - 每次请求时清理过期记录(比如1分钟前的),再检查当前IP的请求次数是否超限
二、垃圾请求防范
1. 参数合法性校验
对传入的answer参数做格式、范围校验,直接拦截无效请求:
- 校验参数是否存在、是否为数字格式
- 可额外限制
answer的取值范围(比如必须是1-100的整数)
2. 无效请求拦截
记录重复查询无效answer的IP,达到一定次数后暂时拦截该IP,避免恶意扫描。
3. 人机验证(可选)
如果函数面向公开访问,可在前端加入验证码验证,将验证结果作为参数传入函数,只有验证通过才执行查询逻辑。
整合后的函数代码示例
exports = async function(payload, response) { // 参数校验:确保answer是有效数字 const answernum = payload.query.answer; if (!answernum || isNaN(Number(answernum))) { response.setStatusCode(400); return { error: "无效参数:answer需为数字格式" }; } // 基于IP的限流处理 const clientIP = context.request.clientIP; const rateLimitColl = context.services.get("mongodb-atlas") .db("answers") .collection("rate_limits"); // 清理1分钟前的限流记录 await rateLimitColl.deleteMany({ timestamp: { $lt: Date.now() - 60000 } }); // 检查当前IP请求次数 const ipRecord = await rateLimitColl.findOne({ ip: clientIP }); if (ipRecord && ipRecord.count >= 10) { response.setStatusCode(429); return { error: "请求过于频繁,请1分钟后重试" }; } // 更新IP请求记录 if (ipRecord) { await rateLimitColl.updateOne({ ip: clientIP }, { $inc: { count: 1 } }); } else { await rateLimitColl.insertOne({ ip: clientIP, count: 1, timestamp: Date.now() }); } // 执行原查询逻辑 const result = await context.services.get("mongodb-atlas") .db("answers") .collection("answers_records") .findOne({ answer: Number(answernum) }); return result; };
补充说明
- 限流阈值(10次/分钟)可根据业务需求调整
- 建议给
rate_limits集合的ip和timestamp字段添加索引,提升查询和清理效率 - 参数校验规则可根据实际业务场景细化,比如限制
answer的取值范围
内容的提问来源于stack exchange,提问作者Ayan Shaikh
相关产品推荐
相关产品推荐

