Nginx出现502 Bad Gateway怎么办?常见原因与完整排查教程

Nginx出现502 Bad Gateway怎么办?常见原因与完整排查教程

访问网站时出现“502 Bad Gateway”,通常表示Nginx本身已经接收到请求,但没有从后端服务获得有效响应。

这里的后端服务可能是:

  • PHP-FPM;
  • Node.js、Java、Python等应用;
  • Docker容器中的Web服务;
  • 另一台反向代理服务器;
  • 负载均衡配置中的上游节点。

因此,遇到502错误时,不应只反复重启Nginx。正确的排查顺序是先确认故障范围,再查看Nginx错误日志,随后检查后端服务、端口或Socket、服务器资源和应用日志。

本文主要适用于Ubuntu、Debian、CentOS、Rocky Linux和AlmaLinux等常见Linux服务器。部分命令需要使用root权限,普通用户可以在命令前添加 sudo

修改生产环境配置前,请备份Nginx及PHP-FPM配置。每次修改后都应先执行配置检查,再平滑重新加载服务。

一、什么是502 Bad Gateway

Nginx可以直接处理静态文件,也可以将动态请求转发给其他程序。

例如,WordPress网站通常由Nginx接收HTTP请求,再通过FastCGI将PHP请求交给PHP-FPM:

用户浏览器 → Nginx → PHP-FPM → WordPress和MySQL

反向代理应用的请求流程可能是:

用户浏览器 → Nginx → Node.js、Java或Python应用 → 数据库及其他服务

如果Nginx无法连接后端、连接超时、后端进程异常退出,或者后端返回了无效响应,用户就可能看到502错误。

502表示网关或代理与上游服务之间存在问题,并不一定说明Nginx进程已经停止。

二、先判断故障范围

排查前先确认502出现在哪些请求中。

可以分别测试:

  • 所有页面都出现502;
  • 只有PHP页面出现502;
  • 静态图片和HTML可以访问;
  • 只有某个接口出现502;
  • 只有访问量高时出现502;
  • 只有上传文件或执行耗时任务时出现502;
  • 只有某一台上游服务器出现502。

如果静态文件可以访问,而PHP页面全部502,问题通常集中在PHP-FPM、FastCGI配置或Socket权限。

如果只有某个接口或耗时任务出现502,应重点检查后端应用日志、执行时间、内存消耗和Nginx超时配置。

如果所有请求都无法访问,还要检查域名是否连接到了正确的Nginx实例,以及Nginx配置是否加载了正确的站点。

三、检查Nginx是否正常运行

首先查看Nginx状态:

systemctl status nginx --no-pager

如果Nginx没有运行,可以继续查看最近日志:

journalctl -u nginx -n 100 --no-pager

检查配置语法:

nginx -t

正常情况下会看到类似结果:

syntax is ok test is successful

如果配置检查失败,应根据输出中的文件路径和行号修复问题,不要在配置错误时直接重启Nginx。

确认配置正确后,可以平滑重新加载:

systemctl reload nginx

重新加载通常不会中断已经建立的正常连接,比直接重启更适合配置变更后的验证。

四、查看Nginx错误日志

Nginx错误日志通常是排查502最有价值的信息。

常见位置包括:

/var/log/nginx/error.log /www/wwwlogs/nginx_error.log /www/wwwlogs/网站域名.error.log

查看最近100行:

tail -n 100 /var/log/nginx/error.log

实时观察新错误:

tail -f /var/log/nginx/error.log

如果不知道实际日志位置,可以查看当前生效配置:

nginx -T 2>/dev/null | grep -n "error_log"

nginx -T 会输出完整配置。把输出提供给其他人分析前,应先检查其中是否包含域名、内部地址或其他敏感信息。

常见错误日志与原因如下:

错误日志关键词常见原因
connect() failed (111: Connection refused)后端服务未运行或端口错误
No such file or directoryPHP-FPM Socket路径不存在或配置不一致
Permission deniedSocket或目录权限不正确,也可能受SELinux限制
upstream timed out后端处理过慢或发生阻塞
no live upstreams配置的上游节点全部不可用
upstream sent too big header后端响应头超过当前缓冲区限制
recv() failed后端进程异常断开连接
Connection reset by peer后端重启、崩溃或主动关闭连接

不要看到502就立即调整超时时间。先根据错误日志确认故障属于连接失败、超时、权限问题还是后端异常。

五、检查PHP-FPM是否运行

WordPress和其他PHP网站出现502时,应优先检查PHP-FPM。

不同系统及PHP版本的服务名称可能不同,例如:

php-fpm php8.1-fpm php8.2-fpm php8.3-fpm php84-php-fpm

查找PHP-FPM服务:

systemctl list-units --type=service --all | grep -i "php.*fpm"

假设服务器使用PHP 8.3,可以执行:

systemctl status php8.3-fpm --no-pager

查看最近日志:

journalctl -u php8.3-fpm -n 100 --no-pager

如果服务处于停止状态,先检查日志和配置,再尝试启动:

systemctl start php8.3-fpm

如果PHP-FPM启动后很快再次退出,不要反复重启。常见原因包括:

  • PHP-FPM配置语法错误;
  • 端口或Socket被占用;
  • 扩展加载失败;
  • 内存不足导致进程被系统终止;
  • 日志或PID目录不存在;
  • 配置文件权限异常。

六、检查Nginx与PHP-FPM监听地址是否一致

PHP-FPM可以通过TCP端口或Unix Socket接收FastCGI请求。

TCP端口方式

PHP-FPM可能监听:

listen = 127.0.0.1:9000

对应的Nginx配置应类似:

location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; }

检查端口是否监听:

ss -lntp | grep ":9000"

如果Nginx连接 127.0.0.1:9000,而PHP-FPM实际监听其他端口,就会出现连接失败。

Unix Socket方式

PHP-FPM可能监听:

listen = /run/php/php8.3-fpm.sock

对应的Nginx配置应类似:

fastcgi_pass unix:/run/php/php8.3-fpm.sock;

检查Socket是否存在:

ls -l /run/php/

如果PHP升级后Socket文件名发生变化,而Nginx仍然引用旧版本路径,就可能出现:

No such file or directory

修改时应以PHP-FPM当前生效配置为准,不要通过手动创建空Socket文件解决问题。

七、检查Socket权限

如果Nginx错误日志出现:

connect() to unix:/run/php/php8.3-fpm.sock failed (13: Permission denied)

说明Nginx进程没有权限访问PHP-FPM Socket。

先查看Nginx运行用户:

grep -n "^user" /etc/nginx/nginx.conf

再查看Socket权限:

ls -l /run/php/php8.3-fpm.sock

PHP-FPM池配置中通常包含:

listen.owner = www-data listen.group = www-data listen.mode = 0660

实际用户可能是 nginxwww-data 或其他面板创建的用户,应根据服务器环境配置。

不要为了临时解决问题直接设置:

chmod 777 /run/php/php8.3-fpm.sock

这种做法扩大了访问权限,而且Socket通常会在PHP-FPM重启后重新创建,手动修改可能失效。正确做法是调整PHP-FPM池的 listen.ownerlisten.group 和 listen.mode,然后检查配置并重新加载服务。

八、检查后端应用端口

如果Nginx反向代理Node.js、Java、Python或Docker应用,先从服务器本机访问后端。

假设Nginx配置为:

location / { proxy_pass http://127.0.0.1:3000; }

检查端口:

ss -lntp | grep ":3000"

直接请求后端:

curl -I --max-time 10 http://127.0.0.1:3000/

如果后端只对特定路径响应,也可以测试实际健康检查接口:

curl -i --max-time 10 http://127.0.0.1:3000/health

可能出现以下结果:

  • Connection refused:应用未监听该端口;
  • 请求超时:应用阻塞、地址错误或网络受限;
  • 返回500:应用已经接收请求,但内部执行失败;
  • 返回200:后端基本可访问,应继续检查Nginx转发配置和请求头;
  • 返回404:端口可访问,但测试路径不存在。

注意,应用如果只监听 127.0.0.1,其他服务器不能通过内网IP访问;如果只监听IPv6地址,Nginx连接IPv4地址也可能失败。

九、检查Docker容器

后端运行在Docker中时,先查看容器状态:

docker ps -a

查看应用日志:

docker logs --tail 100 容器名称

检查端口映射:

docker port 容器名称

查看容器重启情况:

docker inspect -f '{{.State.Status}} {{.State.Restarting}} {{.RestartCount}}' 容器名称

常见问题包括:

  • 容器已经退出;
  • 应用在容器内启动失败;
  • 容器没有发布对应端口;
  • Nginx连接了错误的宿主机端口;
  • 应用只监听容器内的 127.0.0.1
  • 容器因内存不足被终止;
  • Docker网络或服务名称配置错误。

不要只执行 docker restart。如果容器不断重启,应根据容器日志修复应用、配置或资源问题。

十、检查服务器CPU、内存和磁盘

服务器资源耗尽会导致PHP-FPM或其他后端进程无法正常响应。

查看负载和内存:

uptime free -h

查看磁盘容量和inode:

df -h df -i

查看占用资源较高的进程:

ps aux --sort=-%mem | head ps aux --sort=-%cpu | head

检查是否发生过OOM:

journalctl -k --since "2 hours ago" | grep -Ei "out of memory|killed process|oom"

如果日志显示PHP-FPM、MySQL、Java或容器进程被OOM Killer终止,应减少进程并发、优化应用内存,或者在评估后增加服务器内存。

单纯重启服务只能暂时恢复,不能解决持续的内存不足。

十一、PHP-FPM进程达到上限

PHP-FPM的 pm.max_children 决定一个进程池能够同时处理的请求数量上限。

如果PHP-FPM日志出现类似信息:

server reached pm.max_children setting

说明当前进程数已经达到配置上限,新请求需要等待,严重时可能引发超时或502。

查找配置:

grep -R "^[[:space:]]*pm.max_children" /etc/php/*/fpm/pool.d/ 2>/dev/null

不同发行版和安装方式的配置路径可能不同,例如:

/etc/php/8.3/fpm/pool.d/www.conf /etc/php-fpm.d/www.conf

不要盲目把 pm.max_children 调得很大。可以先观察单个PHP-FPM进程的内存:

ps --no-headers -o rss,cmd -C php-fpm | sort -n

粗略估算时,需要确保:

PHP-FPM可用内存 ÷ 单个PHP进程在业务高峰时的实际内存 ≥ pm.max_children

同时还要为Nginx、MySQL、系统和其他服务保留内存。

如果请求长期占用PHP进程,应继续检查慢查询、外部接口、插件和应用代码,而不是只增加进程数量。

十二、后端处理超时

Nginx官方文档中,fastcgi_read_timeout 和 proxy_read_timeout 默认值通常为60秒。它们限制的是两次连续读取之间允许等待的时间,而不是整个响应传输的总时间。

PHP-FPM场景可以配置:

location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_read_timeout 120s; }

反向代理场景可以配置:

location / { proxy_pass http://127.0.0.1:3000; proxy_connect_timeout 10s; proxy_read_timeout 120s; proxy_send_timeout 120s; }

修改后检查并重新加载:

nginx -t && systemctl reload nginx

增加超时时间只适用于业务确实需要较长执行时间的情况,例如数据导入、报表生成或受控的后台任务。

如果普通页面也要等待几十秒,应该优先排查:

  • MySQL慢查询;
  • 第三方接口超时;
  • DNS解析异常;
  • PHP插件阻塞;
  • 文件锁;
  • 应用死循环;
  • 磁盘IO过高;
  • 后端线程或连接池耗尽。

无限增加超时时间会让请求占用连接和进程更久,可能进一步放大故障。

十三、上游响应头过大

如果错误日志出现:

upstream sent too big header while reading response header from upstream

常见原因包括:

  • Cookie过多或过大;
  • 应用返回大量响应头;
  • 登录状态或Session数据异常;
  • 上游返回多个体积较大的 Set-Cookie
  • 应用错误地把大量数据写入响应头。

PHP-FPM场景可能涉及:

fastcgi_buffer_size 32k; fastcgi_buffers 8 16k;

反向代理场景可能涉及:

proxy_buffer_size 32k; proxy_buffers 8 16k;

这些数值只是示例,不应直接复制到所有服务器。应先检查浏览器Cookie和后端响应头,优先修复异常数据,再根据实际响应大小调整缓冲区。

十四、检查SELinux

在启用SELinux的CentOS、Rocky Linux或AlmaLinux服务器上,即使文件权限看起来正常,安全策略也可能阻止Nginx访问Socket或连接网络后端。

查看状态:

getenforce

查看近期拒绝记录:

ausearch -m AVC -ts recent 2>/dev/null | tail -n 50

不要把永久关闭SELinux作为默认解决方法。应根据拒绝日志修复文件安全上下文、布尔策略或服务配置。

为了测试而临时改变安全策略前,也应明确影响范围并准备恢复操作。

十五、检查上游服务器配置

使用 upstream 配置多个后端时,示例可能如下:

upstream app_backend { server 10.0.1.10:8080; server 10.0.1.11:8080; } server { location / { proxy_pass http://app_backend; } }

如果错误日志出现:

no live upstreams

应分别检查每个节点:

curl -I --max-time 10 http://10.0.1.10:8080/ curl -I --max-time 10 http://10.0.1.11:8080/

同时确认:

  • 后端服务是否运行;
  • 内网路由是否正常;
  • 安全组和防火墙是否允许访问;
  • 端口是否正确;
  • 健康检查是否与应用路径匹配;
  • 所有节点是否同时进入不可用状态。

在没有理解请求是否可以安全重试之前,不要随意扩大 proxy_next_upstream 的重试范围,尤其是涉及支付、创建订单和修改数据的POST请求。

十六、面板服务器如何排查

宝塔、1Panel等面板会改变配置目录、日志位置和PHP服务名称,但排查原则不变:

  1. 查看网站对应的Nginx错误日志;
  2. 检查PHP或应用进程状态;
  3. 对比Nginx与后端监听地址;
  4. 检查服务器资源;
  5. 修改配置前创建备份;
  6. 修改后执行Nginx配置检查。

面板中的“重启PHP”和“重启Nginx”可以用于恢复服务,但如果问题重复发生,仍应根据日志查找进程退出、资源不足或配置不一致的根因。

十七、502快速排查流程

可以按照下面的顺序执行。

第一步:检查Nginx

systemctl status nginx --no-pager nginx -t

第二步:查看错误日志

tail -n 100 /var/log/nginx/error.log

第三步:检查后端服务

PHP网站:

systemctl list-units --type=service --all | grep -i "php.*fpm"

反向代理:

ss -lntp curl -I --max-time 10 http://127.0.0.1:后端端口/

第四步:检查监听配置

确认以下配置一致:

Nginx fastcgi_pass ↔ PHP-FPM listen

或者:

Nginx proxy_pass ↔ 应用实际监听地址和端口

第五步:检查资源

free -h df -h df -i uptime

第六步:检查后端日志

journalctl -u 后端服务名称 -n 100 --no-pager

第七步:验证配置

nginx -t

第八步:平滑重新加载

systemctl reload nginx

十八、常见错误处理对照表

现象优先检查常见处理方向
所有PHP页面502PHP-FPM状态启动服务并检查退出原因
静态文件正常、动态页面502FastCGI配置对比Socket或端口
Connection refused后端监听端口启动应用或修正端口
No such fileUnix Socket路径修正Nginx与PHP-FPM配置
Permission deniedSocket权限、SELinux修正用户、组及安全策略
upstream timed out应用和数据库性能查慢请求,再评估超时设置
高峰期出现502CPU、内存、进程池优化应用并评估容量
容器应用502容器状态和端口映射查容器日志与监听地址
删除或升级PHP后502服务名和Socket变化更新Nginx的FastCGI地址
too big headerCookie和响应头修复异常响应,再调整缓冲区

十九、如何减少502再次发生

修复故障后,可以采取以下措施:

  • 为Nginx、PHP-FPM和应用配置日志轮换;
  • 监控CPU、内存、磁盘和inode;
  • 监控后端端口和健康检查接口;
  • 记录PHP-FPM进程池使用情况;
  • 为应用配置慢请求和慢查询日志;
  • 对数据库和第三方接口设置合理超时;
  • 使用进程管理器自动恢复异常应用;
  • 更新PHP或部署新版本后检查Socket路径;
  • 在上线前执行Nginx配置检查;
  • 对重要业务准备回滚方案;
  • 在多节点架构中避免所有实例同时重启。

监控告警应尽量早于用户发现故障。例如,可以在后端健康检查失败、PHP-FPM进程接近上限或服务器内存持续不足时提前通知。

总结

Nginx出现502 Bad Gateway,通常是Nginx与后端服务之间的通信发生异常。

最有效的排查路径是:

确认故障范围 → 检查Nginx状态 → 查看Nginx错误日志 → 检查PHP-FPM或后端应用 → 对比Socket及端口 → 检查权限和SELinux → 检查CPU、内存、磁盘 → 分析应用与数据库性能 → 验证配置并重新加载

遇到502时,重启服务可能暂时恢复访问,但日志才能说明真正原因。只有根据错误信息修复监听地址、权限、资源不足或应用阻塞等根因,才能避免故障反复出现。

参考资料

  • Nginx官方文档:FastCGI模块
  • Nginx官方文档:HTTP Proxy模块
  • Nginx官方文档:请求处理方式
  • PHP官方手册:PHP-FPM配置
  • systemd官方手册:journalctl

知识库

Linux服务器磁盘空间满了怎么办?从定位到安全清理完整教程

2026-7-30 14:52:57

知识库

2026年云服务器优惠怎么选?首购价格、续费成本与避坑指南

2026-7-31 17:15:07