本文目录导读:

我来详细介绍 PHP 性能问题的排查方法和工具,从简单的到专业的逐步深入。
基础排查方法
简单日志分析
// 开启慢查询日志(PHP-FPM) ; php.ini 配置 request_slowlog_timeout = 5s request_slowlog_file = /var/log/php-fpm/slow.log
代码级计时
// 简单的代码计时
$start = microtime(true);
// 你的代码
$elapsed = microtime(true) - $start;
error_log("执行时间: {$elapsed}s");
自带函数分析
// 使用 PHP 内置的性能函数 $start = memory_get_usage(); // 代码 $peak = memory_get_peak_usage();
专业工具使用
Xdebug Profiler
// php.ini 配置 [xdebug] xdebug.mode = profile xdebug.output_dir = /tmp/profiler xdebug.profiler_output_name = cachegrind.out.%p // 生成的分析文件需要用工具查看
使用 PhpStorm 或 KCacheGrind 查看:
# 安装分析工具 sudo apt-get install kcachegrind # 打开分析文件 kcachegrind /tmp/profiler/cachegrind.out.12345
XHProf / Tideways
// XHProf 安装(php 8.0+ 推荐) pecl install xhprof // 配置 [xhprof] extension=xhprof.so xhprof.output_dir="/tmp/xhprof" // 使用示例 xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY); // 你的代码 $data = xhprof_disable();
Blackfire.io
// 专业性最强的工具 // 安装扩展 composer require blackfire/php-sdk // 使用示例 $probe = new \Blackfire\Probe(); $probe->enable(); // 你的代码 $probe->disable();
实时监控工具
PHP-FPM 状态页面
# nginx 配置
location ~ ^/fpm-status$ {
access_log off;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php-fpm.sock;
}
使用 top/htop 监控
# 查看进程 CPU 占用 top -H -p $(pgrep -f php-fpm | head -1) # 实时查看 PHP-FPM 进程 htop | grep php-fpm
strace 系统调用分析
# 跟踪 PHP 进程的系统调用 strace -p PID -f -e trace=file,network,memory # 统计各类系统调用 strace -c -p PID
数据库性能排查
慢查询日志
-- MySQL 配置 SET GLOBAL slow_query_log = ON; SET GLOBAL long_query_time = 2; -- 查看慢查询 SHOW VARIABLES LIKE 'slow_query_log%';
数据库查询分析
// 使用 Laravel 查询分析
DB::listen(function ($query) {
Log::info($query->sql, $query->bindings, $query->time);
});
内存泄漏排查
内存监控
// 监测内存使用
$memory_cache = [];
function memory_usage() {
$size = memory_get_usage(true);
$unit = ['b','kb','mb','gb'];
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
// 定期输出
register_tick_function(function() {
if (memory_get_usage() > 100 * 1024 * 1024) {
error_log("内存使用过高: " . memory_get_usage());
}
});
完整排查流程
系统级检查
# 检查整体性能 top -u www-data free -m iostat -x 1 vmstat 1 # 检查 PHP-FPM 状态 /usr/sbin/php-fpm -t systemctl status php-fpm
应用级检查清单
// 性能检查清单
[
'响应时间' => '正常 < 200ms,慢查询 > 500ms',
'内存使用' => '单请求 < 64M,平局 < 32M',
'CPU使用' => '高峰 < 80%,平均 < 40%',
'数据库' => '查询时间 > 1s 需要优化',
'缓存' => 'Redis 命中率 > 95%',
'流量' => 'Nginx 错误日志要关注 5xx',
]
常见性能问题定位
// 场景1:页面加载慢 // - 检查网络请求时间 // - 数据库查询次数和效率 // - PHP 执行时间 // - Redis/缓存使用情况 // 场景2:内存溢出 // - 是否有循环引用 // - 是否无限递归 // - 是否处理超大数组 // - 是否有未释放的资源 // 场景3:CPU 过高 // - PHP 无限循环 // - 大量正则操作 // - 复杂的算法 // - 循环 SQL 查询
性能优化建议
// 1. 使用 OPcache
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
// 2. 使用关系缓存
// Redis 示例
$redis = new Redis();
$cache_key = 'product_' . $id;
if (!$data = $redis->get($cache_key)) {
$data = $this->getProduct($id);
$redis->set($cache_key, serialize($data), 3600);
}
// 3. 数据库索引
// 确保常用查询字段都有索引
CREATE INDEX idx_product_id ON products (product_id);
// 4. 批量处理
// 不要循环插入
DB::table('users')->insert($bulkData); // 批量插入
实用命令行工具汇总
# 常用命令汇总 php -i | grep "Configure" # PHP 配置信息 php -m # 启用模块 php --ini # 加载的配置文件 # 内存和CPU pidstat -p PID 1 # 进程性能 sar -u 1 3 # CPU 使用率 sar -r 1 3 # 内存使用率 # 网络 netstat -an | grep :80 # 端口连接 iftop # 流量监控 # 应用日志 tail -f /var/log/php-fpm/error.log tail -f /var/log/nginx/access.log
建议采用的分层排查策略
- 第一层:先看响应时间和错误日志
- 第二层:检查服务器资源(CPU、内存、IO)
- 第三层:分析数据库查询和索引
- 第四层:使用 Profiler 找出具体函数耗时
- 第五层:代码审查,算法优化
最后建议:先解决 80% 的大问题(如 N+1 查询、缓存缺失),再优化小细节,不要过度优化,确保可维护性。