Nginx限流因共享内存不足而静默失效,表现为大量请求显示“limiting requests, excess”却无“rejected”,debug日志可捕获“zone is full”,需检查zone配置合法性、容量估算及access.log中$limit_req_status状态。

排查 Nginx 限流限速是否因共享内存不足而失效,关键在于识别“静默失败”——它通常不报错,而是漏放请求或拒绝连接。真正的问题线索藏在日志行为、调试输出和配置一致性中,而不是直接翻 error_log 找“shared memory”字样。
看 error.log 里有没有反复出现的限流提示但无拒绝
打开 error.log,搜索:
limiting requests, excess:
如果大量请求显示类似 limiting requests, excess: 1.000 by zone "perip",但同一客户端 IP 却始终没被拒绝(即没出现 rejected),说明该 zone 已满:新 key 插不进去了,Nginx 只能跳过计数,导致本该限流的请求“漏网”。
- 同一 IP 多次命中相同 excess 值 → 它还在被计数,zone 没满
- 大量不同 IP 都只显示 excess 但无 rejected,且 IP 分布远少于预期 → zone 空间耗尽,新 IP 被静默丢弃
必须开 debug 日志才能看到“zone is full”
默认 error_log 级别完全不记录共享内存区满载事件。临时启用 debug 才能捕获真实状态:
- 在 nginx.conf 中加一行:error_log /var/log/nginx/error.log debug;(仅诊断用)
- 重载配置:nginx -s reload
- 搜索日志:grep "zone.*is full" /var/log/nginx/error.log
典型输出:limit_req: zone "perip" is full, failed to insert key "192.168.1.100"
核对 zone 配置是否合法、大小是否够用
很多“异常”其实源于配置本身无效或过小:
- 运行 nginx -t:若 zone=xxx: 或 zone=xxx:0m,会报 [emerg] zero size shared memory zone(但该错误不写入 error_log)
- 用 nginx -T | grep limit_req_zone 查所有 zone 定义,确认格式为 zone=name:size(如 zone=ip:16m)
- 估算容量:IPv4 地址按约 64–128 字节/key 计,10m zone 最多存约 8 万独立 key;10 万活跃 IP 至少配 16m
结合 access.log 和 $limit_req_status 验证实际效果
单看 error.log 不足以判断限流是否真失效,需联动访问日志:
- 在 log_format 中加入:$limit_req_status,例如:
log_format main '$remote_addr – $request_time $limit_req_status'; - 观察 access.log 中的状态:
hit(命中限流)、miss(未命中)、rejected(被拒绝)
若大量本该被限的请求显示 miss,且 client IP 数远超 zone 容量 → 共享内存已撑不住


















