排查upstream节点过载需聚焦日志行为痕迹:集中出现connect() failed (111)、upstream timed out、no live upstreams、prematurely closed connection;结合access.log中$upstream_addr与$upstream_status分布定位异常节点,并通过$upstream_connect_time与$upstream_header_time对比判断瓶颈在接入层还是业务逻辑层。

排查 upstream 节点过载导致的拒绝服务,关键不是找“过载”这个词,而是识别它在 Nginx 日志中留下的典型行为痕迹:连接被拒、响应延迟、重试失败、状态异常。这些现象往往集中爆发,且与特定后端地址强关联。
看 error.log 中的连接拒绝和超时模式
真正反映 upstream 过载的报错往往成片出现,重点盯以下几类:
- connect() failed (111: Connection refused):后端进程已崩溃、未监听端口,或连接队列溢出(如 listen.backlog 被打满);
- upstream timed out while connecting to upstream:建连阶段就卡住,常见于后端负载过高、accept() 阻塞或进程无响应;
- no live upstreams while connecting to upstream:所有节点都被健康检查标记为不可用,极可能因持续超时触发主动下线;
- upstream prematurely closed connection:后端主动断连,常因 Spring Boot/PHP-FPM 等默认空闲超时短于 Nginx keepalive 设置,大量连接被回收后无法及时重建。
查 access.log 中的 $upstream_addr 和 $upstream_status 分布
这是定位哪台节点过载最直接的方式:
- 提取最近 2–5 分钟内各 upstream 地址的请求频次:awk '$4 > "['$(date -d '3 minutes ago' +[%d/%b/%Y:%H:%M)']" {print $NF}' /var/log/nginx/access.log | grep -v '[-*]' | sort | uniq -c | sort -nr;
- 若某 IP:Port 请求量远高于其他节点(例如 3 倍以上),且同时伴随高错误率或长响应时间,基本可锁定该节点过载;
- 检查 $upstream_status 字段:若大量请求对应 status 为空或为 “502/504”,而 $upstream_addr 固定指向同一地址,说明问题集中在该实例。
结合耗时字段判断瓶颈归属
别只看报错,要量化真实延迟发生在哪一环:
- 若 $upstream_connect_time 高(如 >500ms),但 $upstream_header_time 正常 → 网络或后端接入层问题,可能是系统 load 高、CPU 抢占严重、或连接队列堆积;
- 若 $upstream_header_time 显著偏高(如 >2s),而 $upstream_connect_time 很低 → 后端业务逻辑阻塞,需查慢 SQL、锁等待、同步远程调用、GC 暂停等;
- 若 $request_time 远大于 $upstream_response_time(如 6s vs 0.2s)→ 问题在 Nginx 侧(如 rewrite 复杂、gzip 压缩大响应体、SSL 握手开销大);两者接近且都高 → 后端整体承压,不单是某节点,而是集群水位已达极限。
验证健康检查是否生效并识别隐性故障
过载节点有时不会立刻被踢出,需确认健康检查机制是否真起作用:
- 检查 upstream 配置中是否启用 health_check 或基于 max_fails/fail_timeout 的被动检查;
- 执行 curl -v http://127.0.0.1:8080/health 直连疑似过载节点,看其自身健康接口是否响应正常、延迟是否超标;
- 观察 $upstream_status 序列:若频繁出现 “504,504,200” 或 “502,504,200”,说明 proxy_next_upstream 在兜底重试,但多数尝试已失败 —— 这是节点濒临不可用的明确信号。


















