核心是看连接状态、查配置偏差、验实际行为:用ss或netstat查ESTABLISHED数是否逼近worker_connections;用nginx -T提取keepalive_timeout等参数是否仍为默认值;结合error.log中超时日志密度判断问题频次;再针对性调优keepalive_timeout略大于客户端空闲等待上限、proxy_read_timeout略高于后端P99耗时,并检查ulimit与内核参数是否达标。

排查 Nginx 在高并发长连接场景下因超时设置不合理导致的连接累积,核心是“看连接状态、查配置偏差、验实际行为”。不靠猜,靠可观测性——重点盯住连接生命周期是否被人为拉长,以及资源是否被空闲连接无效占用。
观察连接堆积现象
先确认问题是否存在,而非直接调配置:
- 用
ss -ant | grep :80 | wc -l或netstat -an | grep :443 | grep ESTAB | wc -l查看 ESTABLISHED 连接数,对比worker_connections设置值(如设为 1024,但 ESTAB 超过 900 且持续不降,大概率已堆积); - 执行
nginx -T 2>/dev/null | grep -E "(keepalive_timeout|proxy_(connect|read|send)_timeout)"快速提取当前生效的超时参数,检查是否仍为默认值(如keepalive_timeout 75s、proxy_read_timeout 60s); - 查看
error.log中是否有大量client timed out或upstream timed out日志,注意时间戳是否密集出现,这反映超时频繁触发而非偶发。
验证 keepalive_timeout 是否过长
这是长连接堆积最常见诱因:Nginx 留着大量空闲连接不放,挤占文件描述符和内存。
- 长轮询类业务中,客户端建连后常空等 10–45 秒才收到响应,
keepalive_timeout应略大于该等待上限(如设为 45s),而非默认 75s 或盲目设成 300s; - 若客户端实际只发一次请求就断开(如某些 JS SDK 实现),可将
keepalive_requests设为 2–3,避免连接复用逻辑延迟释放; - 用
curl -v http://your.site/ --header "Connection: keep-alive"配合抓包(如tcpdump -i any port 80),确认连接是否真在空闲期被保持,且超时后是否正常 FIN 关闭。
检查代理层超时是否错配
后端响应慢 + Nginx 等待过久 = 连接卡死在 upstream 队列里。
-
proxy_read_timeout必须略高于后端最长处理耗时(例如后端平均响应 8s、P99 为 38s,则设为 45s),低于此值会频繁触发 504; -
proxy_connect_timeout和proxy_send_timeout宜保守(如 2–5s),防止因后端宕机或网络中断导致 Nginx 主动连接长期挂起; - 禁用无意义重试:
proxy_next_upstream off或仅限error timeout http_500,避免单个失败请求反复占用新连接。
确认系统与内核级限制是否成为瓶颈
配置再合理,若底层资源见顶,连接照样堆积。
- 检查
ulimit -n输出是否 ≥worker_processes × worker_connections,否则连接数未达配置上限就已报too many open files; - 运行
cat /proc/sys/net/core/somaxconn和cat /proc/sys/net/core/netdev_max_backlog,确保不小于 4096,避免 SYN 队列溢出丢包; - 启用
reuseport(在listen指令后加reuseport),让多个 worker 进程能各自监听端口,缓解 accept 队列争抢。


















