验证 limit_conn 资源释放是否及时,需通过 hey 压测(-disable-keepalive)、共享内存计数检查、ss 统计 ESTABLISHED 连接、错误日志分析、keepalive_timeout 设置及日志 $limit 字段变化五方面交叉确认。

测试 limit_conn 在高并发下资源释放是否及时,关键不是看“有没有限”,而是看“限完之后连接是否真正断开、内存是否回收、新连接能否立刻补上”。这需要从连接生命周期、共享内存状态和系统级指标三方面交叉验证。
观察连接建立与断开的实时行为
用 hey 强制新建连接(避免 keepalive 复用干扰):
-
加
-disable-keepalive:确保每个请求都走独立 TCP 握手,真实模拟连接数增长 - 示例:
hey -n 100 -c 20 -disable-keepalive http://your-site.com/,若配置了limit_conn perip 5,应看到约 15 个请求失败(返回 503),其余 5 个成功并快速完成 - 成功请求结束后,立即再发一轮相同压测——如果资源释放及时,第二轮仍能稳定放行 5 个;若卡住或延迟上升,说明连接未及时关闭或 TIME_WAIT 堆积
检查共享内存区域的实际使用率
limit_conn 的计数存在共享内存中,不释放会导致后续连接持续被拒:
- 执行
nginx -T | grep limit_conn_zone确认 zone 名称和大小(如zone=perip:10m) - 用
ss -tn state established | grep :80 | wc -l统计当前 ESTABLISHED 连接数,应接近你设的阈值(如 10),且不随压测次数线性累积 - 查错误日志:
tail -f /var/log/nginx/error.log | grep "limiting connections",反复触发后若日志持续刷出,说明旧连接未退出、新连接不断撞上限
验证空闲连接是否被 timeout 主动清理
keepalive 连接会一直占着配额,必须靠超时机制释放:
- 确认配置中设置了
keepalive_timeout 15;(推荐 10–30 秒),否则长连接会长期锁定配额 - 压测后等待 20 秒,再执行
ss -tn state established | grep :80 | wc -l,数值应明显回落至接近 0 或基础水位 - 若仍维持高位,检查是否被 CDN 或前端代理复用了连接(此时
$binary_remote_addr可能是代理 IP,需配合real_ip_header修正)
日志里追踪单个 IP 的连接状态变化
在 log_format 中加入关键字段,直接看到释放逻辑:
- 添加:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $limit $limit_key'; - 正常流程中,同一 IP 的日志行里
$limit字段会先显示数字(如5),几秒后变为破折号-或空,代表该连接已退出、配额释放 - 若长时间显示相同数字,说明连接卡住或客户端未主动 FIN,需排查后端响应阻塞或 proxy_pass 超时设置


















