PHP开发者分析代码执行效率、查看性能瓶颈除了打断点之外,还可以使用一些扩展工具来进行智能分析,常用的有xdebug、xhprof。本文主要记录xhprof的安装、使用过程以及遇到的一些问题。
1、安装xhprof扩展
sudo wget http://pecl.php.net/get/xhprof-0.9.4.tgz
sudo tar -zxvf xhprof-0.9.4.tgz xhprof-0.9.4
cd xhprof-0.9.4/extension
sudo /usr/local/php/bin/phpize
sudo ./configure --with-php-config=/usr/local/php/bin/php-config
sudo make
sudo make install
成功后提示如下:
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/
2、修改php.ini
sudo vi /usr/local/php/etc/php.ini
增加如下配置:
extension=xhprof.so
xhprof.output_dir=/tmp/xhprof
重启php-fpm:
sudo /etc/init.d/php-fpm restart
3、配置web查看分析结果
假设web服务器的根目录是:/home/www
cd xhprof-0.9.4
cp -rf xhprof_html /home/www/xhprof/
cp -rf xhprof_lib /home/www/xhprof/
web服务器使用Nginx,配置如下:
server {
listen 80;
server_name local.xhprof.com;
root /home/www/xhprof/xhprof_html;
index index.html index.php;
location ~ \.php$ {
fastcgi_pass touch_fastcgi;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
重启Nginx
sudo /etc/init.d/nginx restart
安装成功后可以通过浏览器查看文档:
http://local.xhprof.com/docs/index.html
基于图形界面查看的话,还需要安装graphviz
sudo yum install graphviz
4、分析代码
<?php
xhprof_enable();
// 以下为要分析的代码.
function showSleep($num = 5)
{
$i = 0;
while ($i++ < $num) {
sleep(1);
}
}
function genData($num = 100)
{
$data = [];
$i = 0;
while ($i++ < $num) {
$data[] = $i * $i;
}
sleep(4);
return $data;
}
showSleep(6);
genData(100);
// 以上为要分析的代码.
// 获取分析结果.
$xhprofData = xhprof_disable();
// 引入xhprof_lib.
$xhprofRoot = '/home/www/xhprof';
include_once $xhprofRoot . "/xhprof_lib/utils/xhprof_lib.php";
include_once $xhprofRoot . "/xhprof_lib/utils/xhprof_runs.php";
// 保存结果.
$xhprofRuns = new XHProfRuns_Default();
$runId = $xhprofRuns->save_run($xhprofData, "xhprof_show");
// 输出报告地址.
echo 'http://local.xhprof.com/index.php?run=' . $runId . '&source=xhprof_show';
5、运行代码输出结果:
http://local.xhprof.com/index.php?run=5bd7ba417aada&source=xhprof_show
6、在浏览器中查看如下:
字段含义如下:
Function Name: | 方法名称。 |
Calls: | 方法被调用的次数。 |
Calls%: | 方法调用次数在同级方法总数调用次数中所占的百分比。 |
Incl.Wall Time(microsec): | 方法执行花费的时间,包括子方法的执行时间。(单位:微秒) |
IWall%: | 方法执行花费的时间百分比。 |
Excl. Wall Time(microsec): | 方法本身执行花费的时间,不包括子方法的执行时间。(单位:微秒) |
EWall%: | 方法本身执行花费的时间百分比。 |
Incl. CPU(microsecs): | 方法执行花费的CPU时间,包括子方法的执行时间。(单位:微秒) |
ICpu%: | 方法执行花费的CPU时间百分比。 |
Excl. CPU(microsec): | 方法本身执行花费的CPU时间,不包括子方法的执行时间。(单位:微秒) |
ECPU%: | 方法本身执行花费的CPU时间百分比。 |
Incl.MemUse(bytes): | 方法执行占用的内存,包括子方法执行占用的内存。(单位:字节) |
IMemUse%: | 方法执行占用的内存百分比。 |
Excl.MemUse(bytes): | 方法本身执行占用的内存,不包括子方法执行占用的内存。(单位:字节) |
EMemUse%: | 方法本身执行占用的内存百分比。 |
Incl.PeakMemUse(bytes): | Incl.MemUse峰值。(单位:字节) |
IPeakMemUse%: | Incl.MemUse峰值百分比。 |
Excl.PeakMemUse(bytes): | Excl.MemUse峰值。单位:(字节) |
EPeakMemUse%: | Excl.MemUse峰值百分比。 |
7、点击[View Full Callgraph]查看图形化结果,标红色的区域是比较耗时的逻辑
8、在Yii2框架中测试的时候出现了nginx报502 Bad Gateway错误,解决方案如下:
xhprof_enable();
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
修改为:
xhprof_enable(XHPROF_FLAGS_NO_BUILTINS | XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);
Yii2输出的图形化结果见下图,可以看出来使用了框架代码流程还是比较复杂的,代码没有性能问题,相对比较耗时的基本是框架的autoload、sql查询和Redis查询。
9、开始还遇到一些其他问题,比如分析报告中显示:
Warning: Invalid argument supplied for foreach() in /home/jm/www/xhprof/xhprof_lib/utils/xhprof_lib.php on line 579
Warning: Invalid argument supplied for foreach() in /home/jm/www/xhprof/xhprof_lib/utils/xhprof_lib.php on line 494
Warning: Invalid argument supplied for foreach() in /home/jm/www/xhprof/xhprof_lib/display/xhprof.php on line 854
出现这种问题的原因一般是逻辑代码没有放在xhprof_enable()和xhprof_disable()之间导致没有报告内容,属于比较低级的问题,但是也查了比较久,在这里记录一下。
10、参看文章如下:
- https://www.cnblogs.com/cnsanshao/p/7087319.html
- https://www.jianshu.com/p/38e3ae81970c
- http://alfred-long.iteye.com/blog/2080572
- https://www.144d.com/?post=287