域名解析后访问502错误?服务器配置问题排查
域名解析已经指向了正确的服务器IP,用 nslookup 或 dig 查也没问题,但浏览器一打开就是 502 Bad Gateway。这种情况其实比“域名解析失败”更隐蔽——它说明请求已经到达了服务器,但服务器在处理请求的过程中出了问题。
502 的本质是网关无法从上游服务获得有效响应。在常见的 LNMP 架构里,Nginx 是网关,PHP-FPM(或 Node.js、Tomcat 等后端)是上游。只要两者之间的通信断了,502 就会出现。这篇文章按排查顺序,从“服务状态 → 配置匹配 → 资源限制 → 安全策略”四个层面把问题拆开讲清楚。
先确认:请求到底走到了哪一层
动手查服务器之前,先用一个简单的方法判断问题范围。
在本地终端执行:
curl -I http://你的域名.com
看返回的状态码。如果返回的是 502,说明请求已经到达了 Nginx,Nginx 也尝试转发给后端了,但后端没给有效响应。如果返回的是“连接超时”或“拒绝连接”,那问题在更底层——端口没监听、防火墙拦了、或者安全组没放行。
确认是 502 之后,登录服务器,从 Nginx 的错误日志开始看:
tail -f /var/log/nginx/error.log
日志里通常会直接给出线索。常见的几条:
connect() failed (111: Connection refused):上游服务没启动,或者监听地址/端口不对
connect() to unix:/run/php/php8.1-fpm.sock failed (2: No such file or directory):Nginx 配置的 socket 路径跟 PHP-FPM 实际监听的路径不一致
upstream timed out (110: Connection timed out):后端响应太慢,超时了
日志指向哪条,排查就往哪个方向走。没有日志的情况下,才需要从头一项项查。
第一层:检查 PHP-FPM(或后端服务)是否在运行
这是 502 最常见的原因,没有之一。Nginx 本身不处理 PHP,它把 .php 请求转发给 PHP-FPM,PHP-FPM 挂了或者根本没启动,Nginx 自然拿不到响应。
systemctl status php-fpm
如果显示 inactive (dead) 或 failed,直接启动:
systemctl start php-fpm
systemctl enable php-fpm
注意版本号。Ubuntu 上 PHP 8.1 的服务名通常是 php8.1-fpm,而不是笼统的 php-fpm。用 systemctl list-units | grep php 确认实际的服务名。
如果服务启动了但立刻又挂掉,查看详细错误:
journalctl -u php8.1-fpm -n 50 --no-pager
常见原因是配置文件语法错误、扩展冲突、或者端口被占用。
第二层:核对 Nginx 与 PHP-FPM 的通信方式是否匹配
PHP-FPM 启动着,但 Nginx 还是连不上,那就要看两者“对不上暗号”。
PHP-FPM 有两种监听方式:Unix Socket 和 TCP 端口。Nginx 的 fastcgi_pass 指令必须跟 PHP-FPM 的 listen 设置完全一致。
先看 PHP-FPM 监听什么:
grep listen /etc/php/8.1/fpm/pool.d/www.conf
可能的结果有两种:
listen = /run/php/php8.1-fpm.sock(Unix Socket)
listen = 127.0.0.1:9000(TCP 端口)
再看 Nginx 配置里写的什么:
grep fastcgi_pass /etc/nginx/sites-enabled/你的站点配置文件
如果 Nginx 写的是 fastcgi_pass 127.0.0.1:9000;,但 PHP-FPM 实际在监听 socket 文件,那就对不上了,502 是必然的。把两者改成一致即可。
如果是 Socket 模式,还要检查权限。Nginx 的 worker 进程(通常是 www-data 用户)必须有权限访问那个 socket 文件:
ls -l /run/php/php8.1-fpm.sock
正常的权限应该是 srw-rw---- www-data www-data。如果属主不是 www-data,或者权限不对,在 PHP-FPM 的 www.conf 里设置:
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
然后重启 PHP-FPM。
第三层:检查资源是否耗尽
服务状态正常、配置也对得上,但流量一上来就 502,或者平时偶尔抽风,问题可能在资源层面。
PHP-FPM 进程池被打满是典型场景。PHP-FPM 的 pm.max_children 限制了同时能处理请求的进程数。当所有子进程都在忙,新请求排队等待,超时后 Nginx 就返回 502。
查看当前进程使用情况:
ps aux | grep php-fpm | wc -l
对比 www.conf 里的 pm.max_children 值。如果实际进程数已经接近或等于上限,就需要调大。但要注意:每个 PHP 进程大约占用 20-30MB 内存,调大之前先看服务器内存够不够。
free -h
如果内存充裕,在 www.conf 里调大:
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
调完后重启 PHP-FPM。
另一个资源陷阱是磁盘空间。根分区满了会导致 PHP-FPM 无法写入 session 文件、日志或临时文件,进而引发 502。用 df -h 检查。
第四层:安全策略是否在“帮倒忙”
配置和资源都没问题,但 502 依旧,问题可能出在安全模块上。
SELinux(CentOS/RHEL 系统) 是经典“背锅侠”。它默认会阻止 Apache/Nginx 向网络后端发起连接。如果 SELinux 开着,即使配置完全正确,Nginx 也连不上 PHP-FPM。
临时验证方法:
setenforce 0
如果 502 立刻消失,说明就是 SELinux 的问题。永久解决方式是放行 httpd 的网络连接权限:
setsebool -P httpd_can_network_connect 1
AppArmor(Ubuntu) 也有类似行为,但相对少见。如果怀疑,可以查看 dmesg | grep apparmor 有没有拒绝记录。
如果用了 CDN 或反向代理
502 不一定发生在“Nginx → PHP-FPM”这一段。如果你的网站前面还有 CDN,或者服务器本身在反向代理另一个服务,502 可能出在回源链路上。
CDN 回源 IP 被源站防火墙拦截是高频原因。CDN 的回源节点 IP 段会随节点扩容动态变化,如果源站安全组白名单没有及时更新,新节点回源时会被拦,客户端看到的就是 502。
排查方法:在 CDN 控制台找到回源 IP 列表,在源站安全组里确认这些 IP 段被放行。同时检查 Nginx 的 proxy_read_timeout 是否短于 CDN 配置的回源超时,避免超时不匹配导致误判。
排查流程总结
遇到“解析正常但访问 502”,按这个顺序走:
第一步:看 Nginx 错误日志,从日志关键词定位方向。Connection refused 指向服务未启动,No such file 指向 socket 路径不匹配,timed out 指向性能或超时问题。
第二步:查后端服务状态。systemctl status php-fpm,没运行就启动,启动失败就看 journal 日志。
第三步:核对 Nginx 与 PHP-FPM 的通信配置。fastcgi_pass 和 listen 必须一致,Socket 模式下还要检查权限。
第四步:查资源。PHP-FPM 进程池是否打满、内存是否耗尽、磁盘是否写满。
第五步:查安全策略。CentOS 上关掉 SELinux 测试,确认是否被拦截。
第六步:如果前面有 CDN,检查回源 IP 白名单和超时配置。
大部分 502 在前三步就能定位。关键不是盲目重启服务,而是先看日志,让日志告诉你问题在哪一层。
CN
EN