← 中文资源

简体中文版本

Nginx 502 Bad Gateway — 上游拒绝连接或提前关闭

通过 error.log 区分连接被拒与上游提前关闭,测试后端地址、监听网卡、超时和代理协议,修复 nginx 502。

阅读英文原文

现象

请求返回 502 Bad Gateway,可能全部或部分接口失败;error.log 出现 connect() failed (111: Connection refused) while connecting to upstream,或 upstream prematurely closed connection while reading response header;静态文件正常,同一站点的 API 路由却 502。

诊断

先读错误日志确认是哪一类失败:

tail -n 100 /var/log/nginx/error.log | grep -E 'upstream|connect|502'

Connection refused 表示目标地址端口没有监听;prematurely closed 表示应用接受了连接但没发完整响应;超时则指向应用处理过慢。随后打印实际生效的代理配置:

nginx -T | grep -n -A8 -E 'upstream|proxy_pass'
curl -v --max-time 5 http://127.0.0.1:3000/health
ss -ltnp | grep 3000

如果在 nginx 主机上 curl 成功但代理仍失败,多半是地址不在同一网络命名空间,或应用只监听 127.0.0.1。容器内 localhost 指向容器自身,必须监听 0.0.0.0。若端口确实在监听仍被拦截,用 getenforce 和 ausearch -m avc -ts recent 排查 SELinux。

修复

确保应用稳定运行并监听所有网卡,把 proxy_pass 指向可达地址与正确端口,容器部署时使用服务名或 Pod IP 并配合健康检查。代理超时与应用真实延迟保持一致:

upstream api {
    server 10.0.3.17:3000 max_fails=3 fail_timeout=10s;
    keepalive 16;
}

proxy_read_timeout 只能缓解慢接口,不能替代修复;不要用关闭 SELinux 强制模式作为长期方案。

验证

用 curl -i https://example.com/api/health 确认返回应用自身的状态码与响应体,同时 error.log 不再出现 upstream 报错。再做一次滚动重启,确认请求始终能落到健康实例;若仅在压测时出现 502,应结合应用日志排查崩溃或超时,而不是先调大超时。