nginx轮询时后端宕机未及时剔除会导致502/504,需检查max_fails/fail_timeout被动健康检查、验证节点连通性、分析error_log中upstream超时或拒绝连接日志,并结合$upstream_addr访问日志定位故障节点。

当 Nginx 使用 upstream 轮询(round-robin)模式时,若某个后端节点宕机但未及时被感知,请求仍可能被转发过去,导致 502、504 或超时失败。排查核心在于:确认节点是否真离线、Nginx 是否已将其标记为不可用、健康检查是否生效、以及失败请求是否恰好打到了异常节点。
检查 upstream 配置是否启用健康检查
Nginx 开源版默认不主动探测后端状态,轮询只是静态分发,节点挂了也不会自动剔除。必须显式配置 health_check(需搭配 location 和 proxy_pass)或使用第三方模块(如 nginx_upstream_check_module),或依赖被动健康检查(fail_timeout + max_fails)。
- 查看配置中是否有
max_fails和fail_timeout,例如:server 192.168.1.10:8080 max_fails=3 fail_timeout=30s; - 确认没有误配
down或backup导致节点被长期忽略 - 若用了
health_check(Nginx Plus 或开源版 1.13+ 配合 resolver),检查对应location是否启用且路径可访问
验证节点实际连通性与 Nginx 感知状态
不要只看服务进程是否运行,要模拟 Nginx 的视角发起连接和请求:
- 在 Nginx 服务器上执行:
curl -I http://192.168.1.10:8080/health(或任意后端提供的健康端点) - 用
telnet 192.168.1.10 8080或nc -zv 192.168.1.10 8080测试 TCP 层是否可达 - 检查 Nginx 内存中的 upstream 状态:启用
stub_status或使用nginx -T | grep -A 10 "upstream"确认配置加载无误;更直接的是通过nginx_upstream_check_module提供的 status 页面(如/status)查看各节点当前状态(down/up、fail count、rise count)
分析错误日志定位失败源头
Nginx 错误日志(error_log)是关键线索,开启 error_log ... debug 可看到更细粒度信息(生产环境慎用):
- 搜索关键词:
upstream timed out、no live upstreams、connection refused、Connection reset by peer - 每条错误行通常附带
upstream:字段,明确写出目标 server,例如:upstream: "http://backend_servers/xxx"或具体 IP+端口 - 结合访问日志(
log_format中加入$upstream_addr和$upstream_status),可查到某次失败请求实际转发到了哪个地址、返回什么状态码
临时验证与快速恢复手段
遇到突发故障,可快速缩小范围并止损:
- 手动执行
nginx -s reload不会中断连接,但会重新加载 upstream 配置——如果之前误配了 down 或 max_fails 过大,重载后可能立即生效 - 临时注释掉疑似故障节点,测试请求是否恢复正常,确认是否为单点问题
- 在 upstream 中为该节点添加
weight=0或down,再 reload,实现“软下线” - 若使用 Consul / Nacos 等服务发现,检查注册中心中该实例是否已注销,Nginx 动态 upstream 是否同步延迟











