php-fpm cpu占用过高核心在于请求卡顿、外部阻塞、配置错配或资源浪费;需四步排查:启用验证慢日志、测算内存设合理pm.max_children、用pidstat查i/o与切换瓶颈、必要时迁至swoole。

PHP 8.1.27-FPM 进程 CPU 占用过高,核心问题往往不在 PHP 版本本身,而在于请求执行卡顿、外部依赖阻塞、配置错配或运行时资源浪费。排查要抓“活证据”,优化要盯“真瓶颈”。下面分四步直击要害:
启用并验证慢日志(slowlog)
这是定位高 CPU 请求最直接的手段。宝塔默认关闭,必须手动打开并确认生效:
- 编辑配置文件:
/www/server/php/81/etc/php-fpm.d/www.conf(注意版本号是 81) - 确保这三行已取消注释且值合理:
slowlog = /www/wwwlogs/php_slow.logrequest_slowlog_timeout = 3s(建议 2–5 秒,太短易误报,太长漏捕获)request_terminate_timeout = 0(关键!设非零值会强杀进程,导致日志写不全) - 检查日志目录权限:
ls -ld /www/wwwlogs/,属主必须是www,否则静默失败 - 测试是否真工作:建一个
test-slow.php,内容为<?php sleep(4); echo 'done'; ?>,访问后执行tail -n 5 /www/wwwlogs/php_slow.log,看到含script_filename和duration的记录才算通
查真实内存与进程池配置
CPU 高常因进程数失控——不是太多,而是单个进程卡住反复 fork 新进程,把系统拖垮:
- 测单进程真实内存:运行
ps --no-headers -o rss -C php-fpm | awk '{sum+=$1} END {print int(sum/NR/1024)" MB"}',例如输出42 MB - 算安全
pm.max_children:
剩余可用内存(总内存 × 0.7)÷ 单进程 RSS ≈ 理论上限 → 再打 0.8 折取值
如 4GB 内存服务器,单进程 42MB → (4096×0.7)÷42 ≈ 68 → 安全值取 54 -
pm.start_servers别拍脑袋设 2 或 5;进宝塔「PHP 设置 → 性能调整」,看「当前运行中进程数」近 5 分钟低谷值(比如常在 8–12),就设为8 - 改完务必执行:
php-fpm-81 -t校验语法,再systemctl restart php-fpm-81(重载不生效)
排除 OPcache 和外部阻塞
很多“CPU 高”其实是 PHP 在等 I/O,但 top 显示为 %CPU —— 实为采样误差或锁竞争假象:
- 确认 OPcache 已启用且参数合理:
php -i | grep opcache.enable→ 必须为On
关键参数建议:opcache.memory_consumption=256opcache.max_accelerated_files=20000(先用find /path/to/web -name "*.php" | wc -l查实际文件数)opcache.revalidate_freq=60(生产环境别设 0) - 用
pidstat -u -w -d 1替代 top:
若cswch/s> 10k → 进程切换过频,调小pm.max_children
若await> 10ms → 查 MySQL 慢查询、Redis 连接池耗尽、未关闭的文件句柄(如lsof -p PID | grep REG) - 数据库重点查:
开启 MySQL 慢日志,用EXPLAIN跑高频 SQL,警惕type=ALL和rows远超返回数
避免 N+1:循环里查数据库 → 改成 JOIN 或批量 IN 查询
必要时升级运行模型
PHP-FPM 是同步阻塞模型,QPS 稳定超过 300–500 仍靠它硬扛,CPU 就是白烧:
- 若业务逻辑允许异步(如通知、导出、支付回调),可将这部分迁至 Swoole TaskWorker 或 Redis 队列
- 对实时性要求高的接口(如秒杀、聊天),考虑用 Swoole HTTP Server 替代 FPM + Nginx 组合
- 切记:不是所有项目都适合 Swoole,先确保现有 FPM + OPcache + 数据库索引已调优到位
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











