宝塔 PHP-FPM 进程 CPU 飙升排查与调优记录

核心导读:记录一次小内存轻量云服务器上 PHP-FPM 频繁占满 CPU 导致 502 的排查过程,包含核心运行参数设置参考、慢日志定位以及恶意请求防范思路。

这几天维护一台 2G 内存的轻量云服务器,上面跑着两个 WordPress 站点。白天访问量稍微多一点,CPU 就会偶尔直接拉满到 100%,接着 Nginx 开始频繁报 502 Bad Gateway。

SSH 连上去用 top 一看,全是 php-fpm: pool www 进程在疯跑。顺手把这次的排查步骤和改完后运行稳定的参数整理成备忘,遇到类似情况的朋友也可以参考。

1. 现场表现与紧急处置

如果站点已经打不开,当务之急是先让业务恢复:

bash
# 查看当前 PHP-FPM 进程数量与占用 ps -ef | grep php-fpm | wc -l # 紧急重载或重启 PHP 服务(以 PHP 7.4 为例) systemctl reload php-fpm-74 # 或者直接在宝塔面板后台“软件商店 - PHP 设置”中点击重启

重启通常能立刻释放 CPU,但如果根源没解决,几分钟或几小时后还会复发。

2. PHP-FPM 关键参数调整

宝塔默认安装 PHP 后的并发设置通常比较激进,特别是对于 1G/2G 这样的小内存机器,默认进程数很容易在瞬时流量进来时把物理内存和 CPU 榨干。

进入宝塔面板 -> 软件商店 -> 对应的 PHP 版本 -> 设置 -> 性能调整,建议切换为 ondemand(按需)或调小 dynamic(动态)的进程数。

不同内存配置下的参考值:

服务器配置运行模式max_childrenstart_serversmin_spare_serversmax_spare_servers建议 Swap 大小
1核 1Gondemand / dynamic102251024 MB
2核 2Gdynamic2055152048 MB
2核 4Gdynamic401010302048 MB

为什么这么设:
每个 PHP-FPM 进程在执行复杂程序(如带多个插件的 WordPress)时,平均会吃掉 30MB 到 60MB 内存。如果 2G 机器把 max_children 设成 50,遇到突发访问,仅 PHP 就能占满 2GB 内存,系统开始频繁换页甚至触发 OOM 杀进程,CPU 就会一直卡在上下文切换和高负载状态。

此外,还可以修改 max_requests(每个子进程处理多少请求后自动重启释放内存),建议设为 5001024,能有效缓解第三方 PHP 扩展偶尔存在的内存泄漏问题。

3. 开启慢日志定位卡顿代码

光改并发参数只是治标,如果某个请求本身执行需要 10 秒,那么只要来几个访客,所有子进程依然会被占满。

在宝塔 PHP 设置的“配置修改”或 pool 配置文件中,开启慢查询日志:

ini
request_slowlog_timeout = 3s slowlog = /www/server/php/74/var/log/slow.log

保存并重载 PHP。当有脚本执行超过 3 秒时,查看日志内容:

bash
tail -n 50 /www/server/php/74/var/log/slow.log

慢日志会直接打印出具体的 PHP 文件和行号。常见原因有:

  1. 某个插件在页面加载时同步请求了挂掉的外部 API(超时卡死)。
  2. 数据库查询缺少索引,产生全表扫描。
  3. 大量文件上传未做限制,直接由 PHP 脚本处理大图裁剪。

4. 为什么改完参数依然会被打崩?

如果在参数合理、慢日志没有明显死锁的情况下 CPU 依旧飙高,通常是受到了非正常流量的访问:

  • 恶意爬虫狂刷动态页面:查看网站访问日志,很多时候是某些搜索引擎蜘蛛或扫描器在无休止抓取搜索页(如 /?s=xxx)或分类归档。动态查询会绕过常规静态缓存,直接由 PHP 计算。
  • 针对后台的暴力破解:比如 WordPress 的 xmlrpc.phpwp-login.php 频繁遭到 POST 攻击。

排查这类问题,可以直接通过 Nginx 访问日志过滤高频 IP:

bash
# 统计访问量最高的前 10 个 IP awk '{print $1}' /www/wwwlogs/your-site.com.log | sort | uniq -c | sort -nr | head -n 10

如果是爬虫或者恶意请求,可以在 Nginx 配置中直接封禁 IP,或者对敏感路径限制访问频率。如果不想手动翻日志维护过滤规则,也可以借助宝塔自带的 Nginx 防火墙插件或网站监控报表工具,快速拦截恶意请求并限制单 IP 的请求频率,把流量挡在 Nginx 层,PHP-FPM 的负载自然就会降下来。

常见问题与解答 (FAQ)

Q 改完 PHP-FPM 性能配置后,需要重启服务器吗?

不需要重启整机,只需要在宝塔面板的 PHP 设置页面点击“重载配置”或“重启”即可让新参数生效。

Q 小内存机器配置 Swap(虚拟内存)会不会严重拖慢磁盘性能?

Swap 的主要作用是防崩溃垫底,避免内存瞬间打满直接宕机;只要物理内存足够,系统不会频繁读写 Swap,因此合理设置 1-2G Swap 是利大于弊的。

返回运维知识库