Nginx反向代理后端接口时为什么一直返回502?
我用Nginx给本地开发的Node.js服务做反向代理,前端请求一发就报502 Bad Gateway,但直接访问后端端口是通的。是不是proxy_pass配置有问题?
我的Nginx配置里写了proxy_pass http://localhost:3000;,后端确实在3000端口跑着,也试过换成127.0.0.1还是不行。
server {
listen 80;
server_name localhost;
location /api/ {
proxy_pass http://localhost:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
第一,确认后端服务真的在跑,用
curl http://localhost:3000/api/health测试下,别被pm2或者nodemon骗了,有时候你以为服务起来了其实已经挂了。第二,检查下Nginx错误日志,位置一般在
/var/log/nginx/error.log,看具体报错是什么。可能是权限问题,比如Nginx用户没有访问本地3000端口的权限。第三,把proxy_pass最后的斜杠去掉试试,改成
proxy_pass http://localhost:3000;。带斜杠会把/api/这个路径去掉,有时候会出问题。第四,加上超时配置,Node.js服务如果响应慢就会被Nginx掐掉:
第五,检查下后端服务有没有绑定到127.0.0.1而不是0.0.0.0,有些框架默认只监听本地回环。
我昨晚刚踩过类似的坑,最后发现是pm2偷偷重启把端口占了。建议你先看日志,502的问题十有八九能在日志里找到线索。
先看一眼Nginx错误日志,路径一般在
/var/log/nginx/error.log,里面会告诉你具体报啥错。最常见的一个坑是IPv6的问题。你写
localhost的时候,系统可能把它解析成::1(IPv6),但Node.js默认只监听127.0.0.1(IPv4),所以Nginx连不上。你直接用curl测一下后端接口能通,是因为curl可能走了IPv4。解决办法很简单,把localhost换成
127.0.0.1,同时确认你的Node.js启动时host要设成0.0.0.0或者127.0.0.1,别让它只监听某个特定IP。代码放这了:
改完记得重启Nginx:
nginx -s reload如果你用的是CentOS或者RedHat,还有个可能是SELinux拦住了,Nginx默认没权限做网络代理。跑一下这个命令:
setsebool -P httpd_can_network_connect 1实在不行就把错误日志贴出来,看具体报啥。