You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker环境下Nginx+PHP7.0-FPM出现502错误,如何排查问题?

一步步排查502 Bad Gateway问题(服务器vs代码层面)

咱们先从服务器环境(Nginx+PHP-FPM+Docker)入手,再逐步验证代码逻辑:

一、服务器环境层面排查

1. 确认PHP-FPM是否正常运行

进入你的Docker容器,执行以下命令检查PHP-FPM进程:

ps aux | grep php-fpm

你应该能看到PHP-FPM的主进程和若干子进程。如果没有任何结果,说明PHP-FPM没启动,赶紧看启动日志找原因:

  • 查看容器内的PHP-FPM日志:tail -f /var/log/php7.0-fpm.log
  • 或者直接看Docker容器日志:docker logs <你的容器ID>

2. 核对Nginx与PHP-FPM的通信配置

502最常见的原因就是Nginx找不到PHP-FPM的通信端点,重点检查:

  • 通信方式(Unix Socket/TCP)
    • 如果用Unix Socket:确认Nginx配置里的fastcgi_pass路径,和PHP-FPM配置(/etc/php/7.0/fpm/pool.d/www.conf)里的listen路径完全一致。比如Nginx里是fastcgi_pass unix:/run/php/php7.0-fpm.sock;,那PHP-FPM的listen也得是这个路径。
    • 如果用TCP:确认PHP-FPM的listen127.0.0.1:9000(或其他端口),Nginx的fastcgi_pass对应写成127.0.0.1:9000;
  • Socket权限:虽然你已经改了,但再确认一次:
    执行ls -l /run/php/php7.0-fpm.sock,权限应该是srw-rw---- 1 www-data www-data ...。如果不是,在PHP-FPM的www.conf里设置:
    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660
    
    然后重启PHP-FPM:service php7.0-fpm restart

3. 修复PATH_INFO无法获取的问题

这个问题虽然不一定直接导致502,但可能影响应用路由,检查Nginx的PHP处理location块里有没有配置:

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    # 其他fastcgi配置(比如fastcgi_pass、fastcgi_index等)
}

确保fastcgi_split_path_infofastcgi_param PATH_INFO这两行存在,并且放在fastcgi_pass之前。

4. 深挖日志细节

你看到的Nginx日志157#157: *622 recv() failed (104: Connection reset by peer),通常意味着PHP-FPM进程主动断开了连接。此时一定要看PHP-FPM的错误日志,有没有进程崩溃的提示:

比如类似child 123 exited on signal 11 (SIGSEGV)的日志,说明PHP进程因为代码错误崩溃了,这时候问题就偏向代码层面了。

二、代码层面排查

1. 先做隔离测试:排除ZMQ影响

写一个极简的PHP测试脚本(比如test.php),放在你的web根目录:

<?php
phpinfo();
echo "<br>PATH_INFO: " . ($_SERVER['PATH_INFO'] ?? '未设置');
?>

访问这个脚本,如果仍然返回502,那肯定是服务器环境的问题;如果能正常输出,说明问题出在你的ZMQ相关代码里。

2. 验证ZMQ扩展是否正常加载

在测试脚本里加上一行:

var_dump(extension_loaded('zmq'));

如果返回bool(false),说明ZMQ扩展没安装好,得检查Dockerfile里的安装步骤:是用包管理安装的php-zmq,还是源码编译的?有没有漏掉依赖?

3. 调试ZMQ代码逻辑

如果ZMQ扩展正常,那逐步排查代码:

  • 连接有效性:你的应用是ZMQ客户端还是服务端?如果是客户端,确认要连接的ZMQ服务端是否在运行(容器内或外部),地址和端口是否正确。比如连接本地服务的话,用tcp://127.0.0.1:5555,先确认这个端口有没有进程在监听:netstat -tulpn | grep 5555
  • 添加错误处理:给ZMQ相关代码加上try-catch,把错误信息写到日志里:
    <?php
    try {
        $context = new ZMQContext();
        $socket = $context->getSocket(ZMQ::SOCKET_REQ);
        $socket->connect("tcp://127.0.0.1:5555");
        $socket->send("测试请求");
        $response = $socket->recv();
        echo $response;
    } catch (Exception $e) {
        error_log("ZMQ错误:" . $e->getMessage());
        echo "出错了:" . $e->getMessage();
    }
    ?>
    
    然后查看PHP错误日志(比如/var/log/php/error.log),看有没有连接失败、超时、发送接收异常的信息。

4. 检查PHP运行限制

如果ZMQ操作耗时过长或内存不足,PHP-FPM会直接终止进程,导致连接重置。可以临时调整php.ini的配置:

memory_limit = 256M
max_execution_time = 60

重启PHP-FPM后再测试。

三、Docker环境特殊检查

  • 启动命令:你的Dockerfile是不是同时启动了Nginx和PHP-FPM?比如用supervisord管理两个进程,或者用&&串联启动命令?如果只启动了Nginx,没启动PHP-FPM,那肯定502。
  • 代码目录权限:确保你的PHP应用代码目录和文件的所有者是www-data,执行chown -R www-data:www-data /var/www/html(假设你的代码放在这个目录)。

内容的提问来源于stack exchange,提问作者Sheela M

火山引擎 最新活动