宝塔面板PHP-FPM进程CPU占用过高的排查与调优记录

核心导读:记录一次低配云服务器上宝塔 PHP-FPM 进程占满 CPU 的真实排查过程,梳理了进程数计算、慢日志定位以及防恶意爬虫耗尽算力的实操处理思路。

上周在维护一台 2 核 4G 的轻量云服务器,宝塔后台频繁报警 CPU 飙到 100%,站点偶尔直接返回 502 Bad Gateway。ssh 登录终端一敲 top,发现视线所及全都是 php-fpm: pool www 进程在疯狂吃算力。顺手把当时的排查排错步骤,以及后来跑得比较稳的参数记录下来,方便以后查阅,也给遇到类似情况的朋友一个参考。

1. 临时恢复与初步观察

当线上业务已经卡死无法访问时,第一件事是先让服务恢复响应,再留存现场做排查:

bash
# 临时平滑重载 PHP 服务(根据自己的 PHP 版本调整,如 php-fpm-74) systemctl reload php-fpm-74

重启后 CPU 会瞬间回落,此时需要盯住 top 或 htop,观察进程是缓慢上升还是瞬间拉满:

  • 如果刚启动就瞬间涌入几十个 php-fpm 进程把 CPU 打满,往往是瞬时并发请求过大,或者遭受了爬虫扫盘;
  • 如果只有 1-2 个进程长期霸占单核 100% 算力不释放,通常是某个 PHP 脚本陷入了死循环或复杂计算。

2. 关键参数设置与内存匹配

宝塔默认安装完 PHP 后,运行模式通常采用 dynamic(动态)。很多站长在网站卡顿后习惯性盲目调大 max_children,但这往往是导致 CPU 和内存雪崩的根源。

一个跑着 WordPress 或 Typecho 的 PHP-FPM 子进程,通常会占用 30MB 到 60MB 内存。如果内存耗尽触发了系统 Swap 频繁换页,CPU 的 iowait 会急剧飙升,表现出来也是 CPU 跑满。

针对不同规格的服务器,可以参考以下这套偏向保守稳定的参数搭配:

服务器配置建议 max_childrenstart_serversmin_spare_serversmax_spare_servers建议 Swap 大小
1核 1G102251024MB
2核 2G2033102048MB
2核 4G4055202048MB
4核 8G801010404096MB

在宝塔面板的【PHP 管理】->【性能调整】中即可修改这些数值。此外,一定要设置 max_requests(每个子进程处理多少请求后自动重启释放内存),建议填 500 到 1000,能有效防止 PHP 第三方扩展的内存泄漏。

3. 开启慢日志抓出具体卡顿代码

如果调整了并发参数后,CPU 依然偶尔被单进程跑死,大概率是程序里有执行过慢的代码(如远程 API 超时、慢 SQL 查询、未加索引)。

可以在 PHP 配置文件中开启慢日志定位真因:

ini
; 记录超过 3 秒的请求 request_slowlog_timeout = 3s slowlog = /www/server/php/74/var/log/slow.log

修改后重载 PHP 配置。当再次出现 CPU 飙高时,直接查看日志:

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

慢日志会精准打印出具体是哪个文件、第几行代码执行了多久,顺藤摸瓜去修补插件或优化 SQL 语句即可。

4. 为什么改完参数后还是会被打崩?

在实际排查中,有超过一半的 CPU 跑满案例不是代码问题,而是网站正在被垃圾爬虫高频抓取。动态内容每次请求都要穿透到 PHP 解析,几个并发爬虫就能把双核服务器拉垮。

此时可以实时查看 Nginx 访问日志:

bash
tail -f /www/wwwlogs/你的域名.log

排查要点:

  1. 检查 User-Agent:很多没有标注良性爬虫标签的 Python 脚本、Go-http-client、SemrushBot 等,可以直接在 Nginx 配置中通过规则直接 return 403。
  2. 开启 OPcache 脚本缓存:在宝塔 PHP 安装扩展处勾选 opcache,能把编译后的字节码常驻内存,大幅减轻 PHP-FPM 重复编译解析的 CPU 开销。
  3. 动静分离与页面级缓存:对于博客类站点,配合 Redis 缓存插件直接输出 HTML 页面,请求不用每次都走完整的 PHP 生命周期,CPU 占用通常能直降 70% 以上。

常见问题与解答 (FAQ)

Q 修改了 PHP-FPM 配置参数后必须重启 PHP 吗?

修改后选择平滑重载(Reload)即可生效,尽量避免直接点击强制重启(Restart),以免中断当前正在处理的正常用户请求。

Q 小内存机器配置 Swap 会不会严重拖慢磁盘寿命?

将系统的 swappiness 调低到 10 左右,Swap 仅在物理内存快耗尽时充当防崩兜底缓冲区,平时几乎不产生持续读写,对现代云硬盘寿命没有明显影响。

返回运维知识库