宝塔切换 PHP 8.4 后出现wp出现 502?一次 ARM 服务器 PHP-FPM 崩溃排查实录

最近在一台基于 ARM64 架构的宝塔服务器上,将 WordPress 网站从 PHP 8.0 切换到 PHP 8.4 后,网站立即出现:

HTML
502 Bad Gateway

切回 PHP 8.0 后网站恢复正常,再切换回 PHP 8.4 又马上 502。

一、故障环境

服务器环境:

  • Ubuntu 22.04.1 LTS
  • ARM64 架构
  • 宝塔面板
  • Nginx
  • WordPress
  • PHP 8.4.25
  • PHP 8.0
  • 网站:www.haibakeji.com

网站切换 PHP 8.4 后,Nginx 虽然正常运行,但访问 PHP 页面全部返回 502。

二、先确认 Nginx 配置

查看网站当前使用的 PHP 版本:

Bash
grep -nE 'server_name|include enable-php' \
/www/server/panel/vhost/nginx/haibakeji.com.conf

结果显示:

Nginx
server_name www.haibakeji.com haibakeji.com;
include enable-php-84.conf;

继续查看 PHP-FPM 的通信 socket:

Bash
/www/server/nginx/sbin/nginx -T 2>&1 | \
grep -n -A8 -B2 'enable-php-84.conf'

实际使用的是:

Nginx
fastcgi_pass unix:/tmp/php-cgi-84.sock;

这说明 Nginx 配置本身没有明显错误,问题更可能出在 PHP-FPM 或 PHP 程序执行过程中。

三、502 的真正含义

查看 Nginx 错误日志:

Bash
tail -100 /www/wwwlogs/haibakeji.com.error.log

关键错误是:

Bash
recv() failed (104: Connection reset by peer)
while reading response header from upstream

这个错误并不一定代表 PHP-FPM 没有启动,也可能代表:

Nginx 已经连接到了 PHP-FPM,但 PHP-FPM 在返回响应之前崩溃了。

继续查看 PHP-FPM 日志:

Bash
tail -100 /www/server/php/84/var/log/php-fpm.log

发现大量类似记录:

Bash
child exited on signal 11 (SIGSEGV - core dumped)

SIGSEGV 就是段错误,说明 PHP-FPM worker 进程直接崩溃,而不是普通的 PHP 语法错误。

四、为什么有时正常,有时 502?

刚开始切换 PHP 8.4 后,网站并不是每次都 502,偶尔还能返回 200。

这是因为 PHP-FPM 通常会启动多个 worker:

Bash
php-fpm: pool www

某些请求没有触发问题时,可以正常返回;当某个请求触发 PHP 进程崩溃后,该 worker 会被 FPM 回收并重新创建。

当越来越多请求触发同样的问题时,所有 worker 都不断崩溃,最终 Nginx 就只能持续返回 502。

所以:

“刚才还能访问”并不能证明 PHP 8.4 是正常的,只能说明当时还没有所有 worker 都崩溃。

五、进一步隔离 PHP 8.4 的问题

先用 PHP 8.4 执行一个简单的 PHP 文件:

PHP
<?php echo "PHP84_OK ".PHP_VERSION."\n";

结果正常:

PHP84_OK 8.4.25Code language: CSS (css)

说明 PHP 8.4 二进制本身可以运行。

接着使用 PHP 8.4 执行 WordPress 首页:

Bash
sudo -u www env -i \
REQUEST_METHOD=GET \
SCRIPT_FILENAME=/www/wwwroot/haibakeji.com/index.php \
SCRIPT_NAME=/index.php \
REQUEST_URI=/ \
HTTP_HOST=www.haibakeji.com \
SERVER_NAME=www.haibakeji.com \
SERVER_PROTOCOL=HTTP/1.1 \
HTTPS=on \
REDIRECT_STATUS=1 \
timeout 12 \
/www/server/php/84/bin/php-cgi

结果进程退出码为:

Bash
139

退出码 139 通常对应 SIGSEGV

六、最终定位到 opcache JIT

分别测试 PHP 8.4 的不同配置:

默认配置:

INI
rc=139

关闭完整 opcache

INI
rc=0

只关闭 JIT:

INI
rc=0

原来的配置是:

INI
opcache.enable = 1
opcache.jit_buffer_size=128m
opcache.jit=1205

测试结果表明:

PHP 8.4 的 JIT 与当前 ARM64、WordPress 代码及插件组合存在兼容性问题,触发了 PHP-FPM 的 SIGSEGV

这里不需要关闭整个 opcache,只需要关闭 JIT 即可。

七、处理方法

备份 PHP 8.4 配置:

Bash
sudo cp -a \
/www/server/php/84/etc/php.ini \
/www/server/php/84/etc/php.ini.codex-backup

编辑:

Bash
sudo vi /www/server/php/84/etc/php.ini

修改为:

INI
opcache.jit_buffer_size=0
opcache.jit=0

然后重启 PHP 8.4:

Bash
sudo /etc/init.d/php-fpm-84 restart

验证配置:

Bash
/www/server/php/84/sbin/php-fpm -i 2>&1 | \
grep -E '^opcache\.jit(_buffer_size)? =>'

正常结果应类似:

INI
opcache.jit => 0 => 0
opcache.jit_buffer_size => 0 => 0

八、顺便处理 WordPress FTP 兼容问题

排查过程中还发现,插件 ultimate-addons-for-gutenberg 在 PHP 8.4 下曾触发:

Bash
TypeError: ftp_fput():
Argument #1 ($ftp) must be of type FTP\Connection, null given

原因是 WordPress 错误地选择了 FTP 文件系统方式。

可以在:

Bash
/www/wwwroot/haibakeji.com/wp-config.php

中加入:

PHP
define( 'FS_METHOD', 'direct' );

这行必须放在:

PHP
require_once(ABSPATH . 'wp-settings.php');

之前。

修改前建议先备份:

Bash
sudo cp -a \
/www/wwwroot/haibakeji.com/wp-config.php \
/www/wwwroot/haibakeji.com/wp-config.php.codex-backup

检查语法:

Bash
sudo /www/server/php/84/bin/php -l \
/www/wwwroot/haibakeji.com/wp-config.php

九、最终验证

连续访问网站:

Bash
for n in 1 2 3 4 5; do
    curl -sk --max-time 12 \
    -o /dev/null \
    -w "attempt_$n HTTP %{http_code}\n" \
    https://www.haibakeji.com/
    sleep 1
done

修复后结果:

Bash
attempt_1 HTTP 200
attempt_2 HTTP 200
attempt_3 HTTP 200
attempt_4 HTTP 200
attempt_5 HTTP 200

同时,PHP-FPM 日志在重启后不再出现新的:

Bash
SIGSEGV - core dumped

十、关于插件更新的判断

这次故障发生在更新插件之后,但从日志和隔离测试来看,暂时不能认定 wp-pagenavi 是直接原因。

更准确的判断是:

  • PHP 8.4 的 JIT 在特定 WordPress 请求路径下触发崩溃;
  • 插件更新可能清理了缓存或触发了新的后台请求;
  • 这让原本隐藏的 JIT 兼容性问题集中暴露;
  • ultimate-addons-for-gutenberg 还额外存在 FTP 文件系统兼容问题。

总结

宝塔切换 PHP 8.4 后出现 502,不一定是 Nginx 配置错误,也不一定是 PHP-FPM 没启动。

如果同时看到:

Bash
recv() failed (104: Connection reset by peer)

以及:

Bash
SIGSEGV - core dumped

就应该重点检查 PHP-FPM worker 是否崩溃。

对于 ARM64 服务器上的 PHP 8.4 WordPress 环境,建议先关闭 JIT:

INI
opcache.jit=0
opcache.jit_buffer_size=0

保留普通 opcache 缓存即可。这样通常可以在保证 PHP 8.4 正常运行的同时,避免 PHP-FPM 因 JIT 兼容性问题不断崩溃。

海拔科技

自媒体人,喜欢网络,热爱研究。本站头条号:星河 熊掌号:海拔科技

相关推荐

WordPress时间函数the_time() 详细解析

之所以找the_time()函数的相关说明还是源于本站现在使用这个主题,刚刚发了一篇文章,被百度秒收,很开心,但是一看百度收录时间显示的是12小时前。 卧槽,这怎么回事,一看文章时间显示的真的是12小时之前,起 …