WordPress 突然卡死:一次 PHP-FPM 队列积压的排查与解决

WordPress 突然打不开,第一反应通常是 Nginx、数据库或服务器宕机。但这次故障里,Nginx 仍在监听 80 和 443 端口,静态文件能正常返回,数据库连接数也没有触顶;真正被堵住的,是只有 3 个工作进程的 PHP-FPM 池。

这不是一次“把机器重启一下就好”的处理,而是一次从现象、队列到外部请求的排查。最终的修复也没有简单把并发调高,而是在 1GB 内存的约束下,为 PHP-FPM 加上慢请求记录、超时终止和进程回收,让下一次异常可追踪、可释放。

01|离线时,服务器其实没有宕机

故障表现为 WordPress 首页和其他动态页面间歇性无响应。最初检查时,Nginx 配置校验正常,80 和 443 端口仍在监听;服务器磁盘没有满,MySQL 进程也在运行。更关键的是,静态文件能立即打开,只有需要 PHP 执行的页面卡住。

这组现象把排查方向从“整台服务器故障”收窄到动态请求链路:浏览器请求进入 Nginx 后,正在等待 PHP-FPM 可用的工作进程。此时即使 Nginx 仍健康,访客看到的仍会是网站无法打开。

02|真正堵住网站的,是 3 个被卡住的 PHP 进程

这台 VPS 是 2 vCPU、约 1GB 内存的小主机。为了避免 PHP 进程本身吞掉过多内存,站点的独立 PHP-FPM 池采用 ondemand 模式,pm.max_children 设为 3。这个上限本身是保守且合理的,但它意味着:只要 3 个工作进程同时被长请求占住,第四个动态请求起就只能排队。

故障现场正是如此:3 个 PHP 工作进程持续执行外部 HTTP/HTTPS 请求,FPM 队列一度积压到 125。它们不是在忙于数据库计算,也不是 CPU 被打满,而是在等待外部服务响应。等到这些旧进程自行退出并由新进程替换,队列回到 0,首页连续请求又恢复到正常响应。

当时没有开启 PHP slowlog,Nginx 的访问日志和错误日志也不足以还原触发路径,因此不能把责任直接归给某个插件。能够确认的是:某次外部调用没有及时结束,耗尽了全部 PHP 槽位。对于 WordPress 来说,邮件、统计、反垃圾、远程 API、云服务同步等功能都可能产生外连,必须靠日志进一步定位,而不是凭感觉停用插件。

03|为什么没有直接把 PHP 并发调大

“把 pm.max_children 从 3 改到 5 或 10”看起来可以让队列短一点,但对这台约 1GB 内存的 VPS 并不稳妥。故障排查时,单个博客 PHP 工作进程实际占用约 75 到 102MB;MySQL 还需要自己的缓冲区,系统也已有 Swap 使用。盲目增加并发,很可能把“少数请求排队”换成“内存紧张、频繁交换甚至整机更慢”。

更合理的顺序是:先限制单个异常请求能占用工作进程多久,记录它卡在哪里,并让长期运行的子进程定期回收。只有在业务确实需要更多并发、且内存升级后,才重新评估工作进程上限。对于小内存主机,稳定的保护机制比更高的数字更重要。

04|实际采用的修复:记录、终止、回收

本次没有改变 pm = ondemand 和 pm.max_children = 3,而是在站点独立的 PHP-FPM 池配置中加入以下保护:

pm.max_requests = 300
request_slowlog_timeout = 15s
slowlog = /home/wwwroot/lnmp26/logs/blog.sinovale.com-php-fpm-slow.log
request_terminate_timeout = 90s
  • pm.max_requests = 300:每个 PHP 子进程处理一定数量请求后退出重建,减少插件或扩展长期累积内存的机会。
  • request_slowlog_timeout = 15s:请求运行超过 15 秒时记录调用栈,为下一次锁定具体代码或插件提供依据。
  • request_terminate_timeout = 90s:外部服务长期无响应时,90 秒后终止该请求,避免它无限占住一个 PHP 槽位。

应用配置前先备份原池文件,再用 PHP-FPM 的配置校验命令检查语法;校验通过后只对该 PHP-FPM 池做平滑重载。Nginx、MySQL 和 VPS 都不需要重启。重载后,首页返回 HTTP 200,FPM 错误日志为空,新的 slowlog 文件也已创建。

05|下一次遇到“网站离线”,先看哪几处

这次故障留下的最重要经验,是把“网站打不开”拆成链路来检查。先区分静态文件和动态页面,再看 Nginx 监听与配置、PHP-FPM 工作进程和队列、MySQL 连接与资源使用。若静态文件正常而动态页面整体卡住,优先查看 FPM 状态和 slowlog,通常比立刻重启整台服务器更接近问题。

下一次若 slowlog 记录到稳定的调用栈,再根据证据检查对应插件、远程接口或超时设置;若需要明显提升动态并发,也应先升级到更充足的内存规格,再重新评估 PHP-FPM 的进程数。日志负责回答“谁卡住了”,超时负责避免“一个请求拖住整个站点”。

对小型 WordPress 主机而言,PHP-FPM 不是一个不起眼的后台组件,而是动态访问的闸门。把它的队列、慢请求和回收机制配置好,才能让站点在外部服务偶发失灵时仍保留基本的自我保护能力。

订阅评论
提醒

0 评论