limit_req_zone内存配置需按实际并发活跃IP数精确计算,单个IP约占64字节,1MB可存约1.6万个IP;应通过日志统计、监控或业务场景估算活跃IP,再乘以64得出所需内存,并预留冗余。

要让 limit_req_zone 真正稳定运行,不能随便写个 10m 就完事。内存配小了,IP 状态存不下,会频繁踢掉旧记录,导致限速失效;配太大又浪费资源,尤其在边缘节点或容器环境里很敏感。核心就一条:按实际活跃 IP 数来算,不是拍脑袋估。
单个 IP 状态占多少内存?
每个被限速的客户端 IP(用 $binary_remote_addr)在共享内存区中占用约 64 字节:
- IPv4 地址二进制表示占 4 字节
- 加上一个 64 位计数器(8 字节)、时间戳、哈希桶指针等管理开销
- 实测和官方文档一致:1MB ≈ 存储 16,000 个 IP 的状态
怎么估算你的活跃 IP 数?
别看日志总数,重点是「并发活跃」——也就是在限速窗口内(比如 1 秒或 1 分钟)真正可能同时触发限速判定的 IP 个数。常用方法:
-
查 Nginx access.log 最近 5 分钟:用
awk '{print $1}' | sort -u | wc -l快速统计去重 IP 数,再乘以 0.3~0.6(因多数 IP 是偶发访问,真正高频的只占一小部分) -
看监控工具数据:比如 Prometheus + nginx-exporter 中的
nginx_http_requests_total{job="nginx"} by (remote_addr),取 topN 的活跃 IP 数 - 按业务场景粗估:面向公众的 API,日活 10 万,峰值并发 IP 通常在 3,000~8,000;内部系统调用,IP 集中,可能只需几百个槽位
内存大小计算公式与示例
直接套用:
所需内存(字节) = 预估活跃 IP 数 × 64
换算成常用单位:
- 5,000 个活跃 IP → 5,000 × 64 = 320,000 字节 ≈ 0.32MB → 建议配 2m~5m(留冗余,防哈希冲突和增长)
- 20,000 个活跃 IP → 20,000 × 64 = 1,280,000 字节 ≈ 1.28MB → 推荐 10m(1MB 存 16k,10m 刚好撑住)
- 超 10 万活跃 IP?建议拆 zone 或结合白名单,避免单 zone 过大影响性能
验证与调优技巧
配置上线后,别只看功能是否生效,要确认内存是否真够用:
- 用
nginx -t && nginx -s reload后,检查 error.log 是否有limiting requests, excess: ...频繁出现但 IP 又很快消失,可能是内存不足导致状态被挤掉 - 执行
nginx -V 2>&1 | grep -o 'limit.*module'确认模块已编译;再用ps aux | grep nginx看 worker 进程 RSS 内存是否异常上涨 - 上线初期可临时加
log_format limitlog '$remote_addr - $status [$time_local] "$request" $limit_status';,观察$limit_status(值为 "-""、"hit" 或 "passed")分布,判断是否大量 IP 被误判或漏判











