阿里云上 nginx 反代本机的 Java 服务,浏览器访问 502,在服务器上 curl http://127.0.0.1:8080/health 返回 200,error_log 只有一行 connect() failed (111: Connection refused),时间点和请求对得上。

一开始怀疑是「SELinux 的 httpd_can_network_connect 关着,nginx 出不去」,查了一圈,方向不对。

把日志和配置对完,能解释这个现象的基本就这几处。后端只监听了 127.0.0.1,nginx 的 proxy_pass 写的是内网 IP。也可能是upstream 里配了两台,其中一台已经下线还在被轮询。

还有一种情况,后端在 IPv6 上监听,nginx 解析的是 IPv4 地址。

先确认后端实际监听的地址

ss -lntp | grep 8080

从 nginx 所在位置再请求一次

curl -sv http://10.0.0.12:8080/health

再往下检查 upstream 里有没有失效节点

grep -n -A5 upstream /etc/nginx/conf.d/*.conf

等前面都确认过,再打开 SELinux 的网络访问布尔值

setsebool -P httpd_can_network_connect 1

同一份数据我导出了两份,一份留底,一份拿来试。

这类问题以前遇到过,但这次的触发条件和上次不一样。

改完先别撤,确认这几项。浏览器访问返回 200,error_log 里不再出现 connect() failed,压测时错误率保持为 0。

curl 通不代表 nginx 通,两者用的网络命名空间和 SELinux 上下文可能不同,反代排查一定要从 nginx 的视角发请求。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189