在 Nginx 中配置 IP 限频(通常使用 limit_req_zone 和 limit_req 指令)时,并没有一个“绝对合适”的固定数值。合适的每分钟请求次数(RPM, Requests Per Minute)完全取决于你的业务场景、服务器性能、API 设计以及预期的用户行为。
盲目设置过高会导致服务器被刷爆,设置过低则会导致正常用户频繁遇到 429 错误。以下是针对不同场景的参考建议和分析逻辑:
1. 常见场景参考值
| 业务类型 | 典型场景 | 推荐限制 (RPM) | 说明 |
|---|---|---|---|
| 静态资源 | 图片、CSS、JS、视频等 | 60 – 120 | 用户刷新页面或加载资源较快,但不应允许高频轮询。 |
| 普通 Web API | 登录、搜索、列表查询 | 30 – 60 | 防止恶意爬虫和脚本自动遍历数据。 |
| 敏感操作 | 登录尝试、密码找回、支付接口 | 5 – 10 | 必须严格限制,防止暴力破解和盗刷。 |
| 高并发/实时接口 | WebSocket 握手、推送通知 | 20 – 40 | 视具体业务逻辑而定,通常需配合令牌桶算法平滑处理。 |
| 公开免费服务 | 第三方开放平台(无认证) | 10 – 20 | 保护自身资源不被滥用。 |
| 已认证 VIP 用户 | 付费高级接口 | 100 – 300+ | 针对特定 User-Agent 或 Header 单独放行更高额度。 |
2. 核心配置原则与策略
单纯设定一个数字往往不够,建议结合以下策略进行动态调整:
A. 区分“突发”与“持续”流量
Nginx 的限流模块支持突发(burst)机制。你可以将平均速率设低,但允许短时间内的突发流量通过。
- 示例配置逻辑:
rate=1r/s(每秒 1 次,即 60 次/分)burst=10(允许瞬间堆积 10 个请求)nodelay(立即处理积压的请求,不等待)- 效果:如果用户在 1 秒内发起 10 次请求,只要不超过总限额,都能通过;如果持续超过 1r/s,多余请求会被拒绝或排队。
B. 基于路径(Location)差异化
不要对所有 URL 使用同一套规则。
/api/login:设置极低限制(如 5 次/分钟)。/api/search:设置中等限制(如 30 次/分钟)。/static/*:设置较高限制或仅做基础防御。
C. 监控与反馈循环
配置完成后,必须观察日志:
- 查看 429 状态码频率:如果大量正常用户(非恶意 IP)频繁收到 429,说明限制过严。
- 分析拒绝原因:确认是单一 IP 攻击还是误伤。
- 灰度测试:先对部分内部 IP 或测试环境生效,观察一段时间后再全量上线。
3. 配置示例
以下是一个典型的 Nginx 配置片段,展示了如何定义每分钟 60 次的限制,并允许 10 次的突发:
# 定义共享内存区域,存储每个 IP 的请求计数
# rate=60r/m 表示每分钟 60 次请求的平均速率
# $binary_remote_addr 表示以客户端 IP 作为键
limit_req_zone $binary_remote_addr zone=one:10m rate=60r/m;
server {
listen 80;
server_name example.com;
# 普通接口:限制每分钟 60 次,允许突发 10 次
location /api/normal {
limit_req zone=one burst=10 nodelay;
# 如果超过限制,返回 429 并记录日志
limit_req_status 429;
proxy_pass http://backend;
}
# 登录接口:限制更严格,每分钟 10 次,不允许突发
location /api/login {
limit_req zone=one rate=10r/m;
limit_req_status 429;
proxy_pass http://backend;
}
}
结论
对于大多数通用 Web 应用,每分钟 60 次(即 1 次/秒)是一个比较安全的起始基准值。
- 如果是登录、注册等安全关键接口,请降至 5-10 次/分钟。
- 如果是静态资源,可适当放宽至 120 次/分钟以上。
- 最佳实践是:从保守值开始(如 30 次/分),运行一周后根据监控日志中的 429 错误率逐步微调,直到找到业务体验与安全性的平衡点。
CLOUD技术笔记