
你的PHP网站打开慢。用户点一下,等两三秒才出来。你以为服务器配置不够,升级了硬件,还是慢。
问题不在硬件,在PHP本身。
一个未优化的PHP应用,和优化后的,响应时间可能差5到10倍。今天从三个层面讲优化:字节码缓存、进程管理、慢查询定位。按顺序做,效果立竿见影。
先看一个数据
一个典型的WordPress站点,不做任何优化,平均响应时间约500ms。开启OpCache后降到200ms。再加上PHP-FPM调优和慢查询优化,可以稳定在100ms以内。
没有换服务器,没有加带宽,只是把PHP的配置调对了。
第一层:OpCache——让PHP不需要重复编译
PHP的执行过程:读取PHP文件→编译成字节码→执行。每次请求都重复这三步,CPU做了大量无用功。
OpCache的作用就是把编译后的字节码存在内存里,下次请求直接用。同一个PHP文件被访问100次,只编译1次。
如何开启:
bash
# 安装OpCache(PHP 5.5+ 已内置,只需启用) sudo apt install php8.1-opcache # Ubuntu
编辑php.ini:
ini
opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=60
重启PHP-FPM后生效。用phpinfo()确认OpCache已启用。
参数解读:
memory_consumption=128:OpCache共享内存大小,建议设64-128MB。不够用会提示“Out of memory”。max_accelerated_files=4000:最多缓存4000个PHP文件。项目大可以调高到10000-20000。revalidate_freq=60:每60秒检查一次PHP文件是否有更新。开发时可以设短一点,生产环境60-180秒合适。
效果:开启后,PHP响应时间通常减少50%-70%。
第二层:PHP-FPM进程管理
PHP-FPM是PHP的进程管理器。它维护一批PHP进程,请求来了分配给空闲进程处理。关键参数调不好,要么进程太少(请求排队),要么进程太多(内存爆炸)。
进程池配置(通常在/etc/php/8.1/fpm/pool.d/www.conf):
ini
pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500
参数解读:
pm = dynamic:动态调整进程数,推荐。pm.max_children = 50:最大进程数。每个PHP进程约占用30-50MB内存,50个进程约1.5-2.5GB内存。根据服务器内存配置,保留30%余量。pm.start_servers = 5:启动时创建5个空闲进程。pm.min_spare_servers = 5:最少保留5个空闲进程。pm.max_spare_servers = 35:最多保留35个空闲进程,超过会杀掉部分。pm.max_requests = 500:每个进程处理500个请求后重启,解决内存泄漏问题。
监控方法:
bash
# 查看PHP-FPM进程数 ps aux | grep php-fpm | wc -l # 查看状态页(需在配置中开启) curl http://localhost/status
如果你发现listen queue(监听队列)经常不为0,说明进程不够,要调高pm.max_children。如果进程数经常接近pm.max_children但listen queue是0,说明刚好够用。
第三层:慢日志定位
有些页面慢,不是PHP-FPM配置问题,是代码写得烂。PHP-FPM的慢日志能帮你找出哪些脚本执行慢。
开启慢日志:
在www.conf里添加:
ini
request_slowlog_timeout = 2 slowlog = /var/log/php-fpm/slow.log
执行超过2秒的请求会被记录到slow.log,包含调用栈,能直接看到卡在哪一行。
分析慢日志:
bash
tail -f /var/log/php-fpm/slow.log
常见问题:
- 数据库查询慢:看到
mysqli_query或PDO::query,去MySQL开慢查询日志加索引。 - 外部API调用慢:
file_get_contents('https://api.xxx')超时,考虑加缓存或异步处理。 - 循环处理大数据:比如遍历上万条数据,优化算法或分批处理。
找到慢的地方,针对性优化。
代码层面的优化建议
1. 使用单引号代替双引号
双引号会解析变量,单引号不会。细微差别,高频调用下能省CPU。
php
$name = 'John'; echo "Hello $name"; // 稍慢 echo 'Hello ' . $name; // 稍快
2. 循环中不要重复调用函数
php
// 慢
for ($i = 0; $i < count($array); $i++) {}
// 快
$count = count($array);
for ($i = 0; $i < $count; $i++) {}
3. 用require_once代替require和include
require_once会检查文件是否已包含,有额外开销。但对于现代PHP应用,这点开销微不足道。优先保证代码清晰,只在瓶颈处优化。
4. 开启Opcache文件重验证
Opcache默认会检查PHP文件是否有更新。生产环境可以把opcache.validate_timestamps设为0,彻底不检查,性能最好。代价是改了PHP文件必须重启PHP-FPM才能生效。
ini
opcache.validate_timestamps=0
真实案例:一个WordPress站点的优化全过程
一个日IP 5000的WordPress站点,平均响应时间1.2秒,首屏加载3秒多。
第一步:开启OpCache,响应时间降到600ms。
第二步:调PHP-FPM参数,pm.max_children从30调到80,响应时间降到400ms。
第三步:开慢日志,发现一个插件执行了INFORMATION_SCHEMA查询,每次请求扫描全库。禁用该插件,响应时间降到200ms。
第四步:加Redis对象缓存,降到100ms以内。
4步优化完,总耗时不到1小时。用户反馈“网站快多了”,服务器CPU使用率从70%降到20%。
负责人说:“原来PHP也可以这么快。”
最后一句
PHP性能优化不是玄学。OpCache、FPM调参、慢日志,三把斧头砍下去,大部分慢请求都能解决。重点不是把某个参数调最大,而是找到真实的瓶颈。
下次你的PHP网站慢了,按顺序排查:开了OpCache没?FPM进程够不够?慢日志里有没有异常?三件事做完,网站通常就能跑进秒开范围。




