nginx轮询不主动检测后端健康,宕机后仍转发请求直至超时,导致卡顿;排查重点是确认nginx是否感知并跳过故障节点,需查error.log中的upstream timed out、no live upstreams等关键错误,验证后端真实状态,并检查max_fails、fail_timeout、proxy_next_upstream等容错配置是否生效。

轮询本身不检测后端健康状态,所以后端宕机后请求仍会发过去,直到超时才失败——这正是卡顿的根源。排查重点不是“有没有宕机”,而是“Nginx是否感知并跳过它”,以及“卡在哪个环节”。
看Nginx错误日志里的关键线索
直接查 /var/log/nginx/error.log,重点关注这几类记录:
- upstream timed out:说明Nginx向某台后端发起连接或等待响应超时,是后端无响应的直接证据
- no live upstreams while connecting to upstream:所有后端都被标记为不可用,整个 upstream 池已空,服务彻底中断
- connect() failed (111: Connection refused):后端进程没起来,端口监听都不存在
- recv() failed (104: Connection reset by peer):后端进程收到请求后立刻断连,常见于应用崩溃后残留进程
验证后端真实状态,别只信Nginx判断
Nginx的健康检查是被动或半主动的,容易滞后。要确认后端是否真挂了,得绕过Nginx直接测:
- 用 curl -I http://192.168.1.10:8080/health(或你实际的健康接口)逐台访问后端IP和端口
- 用 telnet 192.168.1.10 8080 或 nc -zv 192.168.1.10 8080 测试端口连通性
- 登录后端服务器,执行 ps aux | grep java(或对应应用进程名)、systemctl status your-app 看服务是否存活
检查Nginx是否配置了基础容错机制
如果 upstream 块里只有 server 192.168.1.10:8080; 这种裸配置,那就没有故障隔离能力。必须确认以下参数已设置:
- max_fails=3 fail_timeout=30s:连续3次失败后,30秒内不再转发请求给这台机器
- proxy_next_upstream error timeout http_500 http_502 http_503 http_504:遇到这些情况就自动转给下一台
- proxy_next_upstream_tries 3:单个请求最多重试2次(默认值为0,即不重试)
缺少其中任意一项,都会导致请求卡在宕机节点上,直到超时(默认60秒),用户明显感知延迟。
抓包确认请求到底发去了哪里
当怀疑Nginx没按预期跳过故障节点时,可在后端服务器上抓包验证:
- 在疑似宕机的机器上运行:tcpdump -i any port 8080 -nn -c 10
- 同时从客户端发起几次请求,观察是否有新包进来
- 如果有,说明Nginx仍在往这台机器发请求——要么 max_fails 没生效,要么故障还没累积到阈值
注意:该操作需在后端机器执行,不能在Nginx本机抓,否则看到的是出向流量,无法判断是否被真正接收。











