nginx worker_connections持续占满并报“1024: too many open files”或502/503错误,大概率是tcp连接未正常释放导致泄漏;需通过ss -s、nginx_status对比worker_connections×worker_processes,重点排查upstream超时配置、后端keepalive处理异常及客户端idle连接堆积,并同步校准ulimit、limits.conf和systemd的fd限制。

当 Nginx 的 worker_connections 被持续占满,出现大量 1024: Too many open files 错误或请求被拒绝(502 Bad Gateway、503 Service Temporarily Unavailable),大概率不是并发突增,而是 TCP 连接未正常释放,发生了连接泄漏。
确认是否真被占满
别只看错误日志,先验证当前连接使用情况:
- 执行
ss -s或netstat -an | grep :80 | wc -l查看系统级 ESTABLISHED 连接数(注意:这包含所有进程) - 用
nginx -T 2>/dev/null | grep worker_connections确认实际配置值 - 通过
curl http://localhost/nginx_status(需启用ngx_http_stub_status_module)查看活跃连接:Active connections:后的数字是当前 Nginx 管理的总连接数(含 idle keepalive) - 对比
Active connections和worker_connections × worker_processes—— 若前者长期接近后者,且Reading/Writing比例异常低、Waiting却极高,说明大量连接卡在 keepalive 等待状态,未及时回收
重点排查上游服务导致的连接滞留
Nginx 本身不主动泄漏连接,但若后端(upstream)响应慢、不发 FIN、或直接断连不通知,Nginx 的 upstream connection 就可能 hang 住,无法复用或关闭。
- 检查 upstream 配置中是否设置了合理的超时:
proxy_connect_timeout、proxy_send_timeout、proxy_read_timeout—— 建议均设为 30s 以内,避免长 hang - 确认后端应用是否正确处理 HTTP/1.1 keepalive:例如 Spring Boot 默认启用 keepalive,但若连接池未配置最大空闲时间或未正确 close 流,会导致 Nginx 的 upstream socket 长期处于 ESTABLISHED 状态
- 用
tcpdump -i any port 8000 -w upstream.pcap抓包观察后端响应行为:是否迟迟不发 FIN?是否在 Nginx 发出 FIN 后无 ACK?是否存在 RST?
检查客户端侧 keepalive 行为与配置失配
客户端(如浏览器、移动端 SDK)若开启长连接但长时间不发新请求,而 Nginx 的 keepalive 设置又过长,就会堆积大量 idle 连接。
- 确认
keepalive_timeout值(默认 65s)是否合理——对高并发 API 服务,建议调低至 15–30s - 检查
keepalive_requests(默认 100):若客户端单连接发起请求极少,该值过高反而延长连接生命周期 - 留意客户端是否发送了
Connection: close,但 Nginx 因配置忽略(如underscores_in_headers on导致 header 解析失败),造成连接未按预期关闭
验证并修复文件描述符限制
即使连接逻辑正常,系统级 fd 限制不足也会表现为“伪泄漏”:
- 运行
ulimit -n查看 nginx worker 进程的 soft limit(常为 1024) - 检查
/etc/security/limits.conf是否为 nginx 用户设置了nginx soft nofile 65536和nginx hard nofile 65536 - 若用 systemd 启动,还需在
/etc/systemd/system/nginx.service.d/override.conf中添加:[Service]<br>LimitNOFILE=65536
然后执行systemctl daemon-reload && systemctl restart nginx











