502错误是nginx与上游服务通信失败所致,非业务代码问题;需查nginx错误日志、确认上游监听状态及权限、修正path_info配置、调优超时与缓冲区参数。

看Nginx错误日志定位第一现场
别猜,先查 /var/log/nginx/error.log。这是唯一能告诉你“Nginx到底卡在哪一步”的地方。
- 出现
connect() failed (111: Connection refused)→ 上游根本没监听,比如php-fpm没启动,或proxy_pass写错了端口 - 出现
upstream timed out (110: Connection timed out)→ 网络不通、防火墙拦截、或上游进程卡死没响应 - 出现
recv() failed (104: Connection reset by peer)→ 上游进程崩溃、被OOM Killer干掉、或PHP脚本执行中异常退出 - 出现
no live upstreams→upstream块里所有节点都不可用(比如健康检查失败、IP写错、端口全连不上)
确认上游服务是否真在跑、且能被Nginx访问到
不能只看 ps aux | grep php-fpm 显示有进程就放心——它可能没监听socket,也可能监听了但权限不对。
- 对PHP-FPM:运行
netstat -lnp | grep php,确认有unix:/tmp/php-cgi.sock或127.0.0.1:9000这类监听项;若只有127.0.0.1:9000但Nginx配置的是unix:/var/run/php/php8.1-fpm.sock,必然502 - 对反向代理(如Tomcat/Node):在Nginx服务器上手动执行
curl -v http://127.0.0.1:8080/health,必须能拿到HTTP 200响应;如果连不通,检查上游是否绑定了127.0.0.1而非0.0.0.0,或SELinux/firewalld是否拦了本地回环 - 对FastCGI类服务:确保
listen.owner和listen.group与Nginx worker进程用户(通常是www-data或nginx)一致,否则socket拒绝连接
ThinkPHP等PATH_INFO路由项目必改Nginx配置
ThinkPHP 5.x/6.x 默认用PATH_INFO模式解析URL,但标准Nginx配置不传递 PATH_INFO 变量,导致PHP-FPM收不到路由参数,直接退出,Nginx收不到响应就报502。
- 错误写法:
location ~ \.php$ { ... fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }——$1为空,PATH_INFO丢失 - 正确写法(推荐):
location ~ \.php(.*)?$ { ... fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $1; }—— 注意正则必须带(.*)?才能捕获$1 - 更稳写法(宝塔/lnmp用户首选):删掉PATH_INFO逻辑,改用
try_files把所有请求兜底给index.php:location / { try_files $uri $uri/ /index.php?$query_string; },再单独配location ~ \.php$块,让ThinkPHP从$_SERVER['QUERY_STRING']解析路由
调大超时和缓冲区,避免“等不及就判死刑”
Nginx默认的 fastcgi_read_timeout 是60秒,而一个导出Excel或跑复杂SQL的ThinkPHP接口可能要90秒——Nginx等不到结果,主动断开连接,上游还在处理,但Nginx已返回502。
- 在
location ~ \.php块里加:fastcgi_connect_timeout 300;、fastcgi_send_timeout 300;、fastcgi_read_timeout 300; - 如果接口返回大JSON或文件流,还要加大缓冲区:
fastcgi_buffer_size 128k;、fastcgi_buffers 4 256k;、fastcgi_busy_buffers_size 256k; - 注意:这些值不能无脑调高。若上游真卡死,只是把502延迟成504,得配合监控查清是慢SQL、内存泄漏还是进程池耗尽
netstat -lnp 和 curl -v 这两步,它们比重启服务管用十倍。











