关键不是怀疑least_conn算法,而是验证Nginx统计的连接数与后端真实承载能力是否一致:需确认配置中明确启用least_conn且无冲突策略,通过上游日志定位504集中节点,登录后端交叉验证ESTABLISHED连接、健康接口响应及应用层状态,并收紧proxy_connect_timeout、proxy_send_timeout和proxy_read_timeout三类超时。

排查 Nginx least_conn 模式下因代理转发超时导致的连接堆积,关键不是怀疑算法本身,而是验证“Nginx 看到的连接数”和“后端真实承载能力”是否一致。504 超时和连接堆积往往同步出现,本质是 least_conn 把请求持续分发给了“账面空闲但实际已卡死”的节点。
检查 least_conn 是否被正确启用且未被覆盖
运行 nginx -T 查看完整生效配置,确认:
- upstream 块第一行明确写了
least_conn;(不能写在其他指令之后) - 没有同时启用
ip_hash、hash $request_uri或random等冲突策略 - 所有 server 行未意外设置
max_fails=0或过长的fail_timeout,否则健康检查失效,异常节点无法剔除
开启上游连接日志,定位超时集中节点
在 upstream 块外定义日志格式,在 access_log 中记录真实分发路径:
log_format upstream_log '[$time_local] $remote_addr → $upstream_addr status:$upstream_status rt:$upstream_response_time';<br>access_log /var/log/nginx/upstream.log upstream_log;
观察 504 日志中 $upstream_addr 是否高度集中在某一台后端 IP。若是,说明 least_conn 正在持续把新请求导给它——但它活跃连接数低,可能正卡在 GC、慢 SQL 或外部依赖上,尚未断连。
交叉验证后端真实状态,而非只信 Nginx 统计
Nginx 的“活跃连接数”仅指已建立 TCP 连接,不反映应用层处理能力。需登录对应后端服务器手动验证:
- 执行
ss -tn state established '( sport = :8080 )' | wc -l(替换为实际端口),对比 Nginx 的keepalive设置值,判断是否大量连接处于 ESTABLISHED 但无数据交换 - 用
curl -o /dev/null -s -w '%{http_code} %{time_total}\n' http://localhost:8080/health测试健康接口响应:若耗时 >3s 或返回非 200,说明应用已不可用 - 检查应用线程池使用率(如 HikariCP 的
ActiveConnections)、JVM GC 频次(jstat -gc <pid>)、慢查询或 Redis 超时日志
收紧超时与连接生命周期,防止“假空闲”误导调度
连接堆积常源于超时太长,让无效连接长期滞留。需三类超时协同控制:
-
proxy_connect_timeout 2s;—— 建连不能拖,避免卡在 SYN 阶段 -
proxy_send_timeout 15s;—— 发完请求后,后端必须及时 ACK 接收 -
proxy_read_timeout 45s;—— 等响应总时长,应略高于业务最长处理时间,但不宜设成 600s
同时在 upstream 中启用 keepalive 32;,并确保后端开启 HTTP keep-alive(如 Tomcat 的 keepAliveTimeout > proxy_read_timeout),避免短连接频繁重建干扰 least_conn 统计。


















