502本质是nginx仍向已下线的上游节点转发请求:因未配置健康检查或fail_timeout机制,旧连接残留导致connect() failed或prematurely closed connection,需检查upstream配置、max_fails/fail_timeout参数、keepalive连接及dns缓存。

故障转移后旧连接未释放引发502,本质是Nginx仍尝试把请求发给已下线的上游节点,而该节点TCP连接已断开或拒绝响应。这类问题在滚动更新、服务摘除、K8s Pod重建或手动下线实例时高频出现,日志里常看到 connect() failed (111: Connection refused) 或 upstream prematurely closed connection,但你确认新节点明明已就绪——问题就卡在“旧连接没清理干净”上。
检查 upstream 连接状态是否残留
Nginx 默认不会主动探测并踢掉失效节点,除非配置了健康检查或 fail_timeout 机制。如果故障转移后没触发自动剔除,它可能还在轮询一个已销毁的 IP:Port。
- 用 netstat -tulnp | grep :upstream_port 确认目标端口当前是否有进程监听(尤其注意是否监听在 127.0.0.1 而非 0.0.0.0)
- 查 Nginx 的 upstream 配置,看是否用了静态 IP 列表(如
server 10.0.1.5:8080;),而非服务发现机制;静态地址在节点下线后不会自动消失 - 执行 curl -v http://old_node_ip:port/health,验证旧节点是否真不可达——如果返回 connection refused 或超时,说明 Nginx 还在往那里发请求
确认 Nginx 是否真正识别到节点失效
即使旧节点宕了,Nginx 也不会立刻停止转发,它依赖 max_fails 和 fail_timeout 组合来判定“失效”。默认值(max_fails=1, fail_timeout=10s)在高并发下容易误判或延迟生效。
- 检查 upstream 块中是否设置了
max_fails=3 fail_timeout=30s这类更稳健的参数 - 查看 error.log 中是否持续出现同一 upstream 地址的失败记录,例如:
[error] ... upstream failed (111: Connection refused) while connecting to upstream, client: ..., server: ..., upstream: "10.0.1.5:8080" - 若日志里反复出现同一个地址失败,且持续时间超过
fail_timeout,但 Nginx 仍在转发,说明该节点未被标记为 down——可能因为失败次数未达max_fails,或配置未重载
验证 keepalive 连接是否滞留旧后端
当启用 keepalive(如 upstream { keepalive 32; })时,Nginx 会复用与上游的长连接。若旧节点下线前已有空闲 keepalive 连接,这些连接不会自动关闭,Nginx 可能继续往它们写数据,导致 upstream prematurely closed connection 类 502。
- 临时禁用 keepalive 测试:注释掉 upstream 中的
keepalive行,reload Nginx,观察 502 是否消失 - 确认 proxy 层启用了 HTTP/1.1 和 Connection header 清理:
proxy_http_version 1.1;<br>proxy_set_header Connection "";
- 检查
keepalive_timeout是否过长(如设为 600s),建议调低至 60s 内,加速陈旧连接回收
排查 DNS 缓存或 IP 地址硬编码问题
如果 upstream 使用域名(如 server api.example.com:8080;),而 DNS 解析结果未及时更新(比如旧 Pod IP 仍缓存在 Nginx resolver 或系统 DNS 缓存中),Nginx 就会持续连向已销毁的地址。
- 在 Nginx 配置中显式指定 resolver,并加
valid=30s:resolver 127.0.0.11 valid=30s;(Docker)或resolver 8.8.8.8 valid=30s; - 避免在 upstream 中直接写域名;改用变量 + resolver 动态解析,或接入 Consul/etcd 等服务发现
- 用 getent hosts api.example.com 或 dig api.example.com 对比本地 DNS 缓存与真实解析结果是否一致











