PHP慢的根源通常不是CPU性能不足,而是opcache未启用、slowlog未配置、max_children设置不当或sys时间过高,需优先排查这些配置和系统指标。

PHP慢不是CPU不够,先看opcache有没有开
绝大多数线上PHP应用卡顿,根本原因不在CPU,而在每次请求都重复编译PHP文件。没开opcache时,哪怕用128核CPU,file_get_contents读一个配置文件都要走完整解析流程。
检查方法很简单:php -i | grep opcache,看opcache.enable是否为On;如果显示off或压根没这一行,说明它根本没加载。
-
opcache.enable=1必须设为1(不能是On字符串) -
opcache.memory_consumption=128建议至少128,小项目64也勉强够用 -
opcache.validate_timestamps=0上线后务必关掉,否则每秒都在检查文件修改时间 - 改完
php.ini必须重启PHP-FPM或Apache,service php-fpm restart
查slowlog比看CPU使用率有用十倍
CPU跑满可能是某条SQL死循环、某个file_put_contents写到NFS挂载点卡住、或者curl_exec没设timeout一直等响应——这些在top里只显示“PHP占98% CPU”,但真实瓶颈根本不在计算能力。
启用slowlog后,PHP会把执行超时的完整调用栈记下来,一眼就能定位到哪行代码、哪个函数拖垮了整个服务。
- 在
www.conf里加:slowlog = /var/log/php-fpm-slow.log - 同时设:
request_slowlog_timeout = 5s(建议从5s开始,别一上来就100ms) - 日志里出现
script_filename和backtrace字段,重点关注require、include、mysqli_query、curl_exec这几类调用 - 注意:
slowlog本身不耗资源,但日志路径磁盘满会导致PHP-FPM进程僵死
升级CPU前先确认是不是max_children配错了
PHP-FPM的max_children不是越大越好。设太高,内存吃紧触发OOM Killer,系统直接杀PHP进程;设太低,请求排队,nginx返回502 Bad Gateway,看着像“CPU不够”,其实是子进程全忙、新请求进不来。
合理值取决于单个PHP进程平均内存占用,而不是CPU核心数。一台16G内存机器,每个PHP进程吃40MB,max_children最多撑到300左右,再多就危险。
- 用
ps aux --sort=-%mem | grep php-fpm看几个worker进程的实际RSS内存 - 计算公式:
max_children ≈ (总内存 × 0.7) ÷ 单进程平均RSS(0.7是安全水位) -
pm = static时,max_children就是固定值;pm = dynamic时,重点看pm.max_children上限 - 改完必须
reload,不是restart,避免请求中断
真要换CPU?先盯住sys时间占比
用top看PHP进程时,注意右上角的%Cpu(s)字段里sy(system time)是否长期高于us(user time)。如果sy持续占30%以上,说明大量时间花在内核态:比如频繁open/stat文件、锁竞争、上下文切换——这时候换更快CPU几乎没用,反而该查I/O或并发模型。
-
pidstat -w -p $(pgrep php-fpm) 1看cswch/s(每秒上下文切换次数),超过5k就要警惕 -
iostat -x 1看%util是否常驻100%,确认是不是磁盘成了瓶颈 - PHP 8.1+ 的
pcntl_fork在某些内核版本下会引发高sy,换成parallel扩展更稳 - 云服务器上
sys高还可能是宿主机资源争抢,这时看cat /proc/vmstat | grep pgpgin比看CPU更有参考价值
硬件升级永远是最后一招。你看到的“PHP慢”,九成藏在opcache开关、slowlog堆栈、max_children水位和sys时间分布里——这些地方不动,换颗EPYC也救不回响应时间。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











