Xhprof 是facebook开源出来的一个php轻量级的性能分析工具,跟Xdebug类似,但性能开销更低,还可以用在生产环境中,也可以由程序开关来控制是否进行profile。
官方已经停止维护这个工具,官方最后发布的版本支持到php5.4以下(不包括5.4)。
官方版本
现在github上维护着的是社区版,支持到php7+。
php7版本
Xhprof 是以php扩展的形式的
本文基于 PHP7.2 版本,讲解 xhprof的安装和使用。
安装 xhprof
# 文件存放目录
cd /var/www
# 下载、解压文件
wget https://github.com/longxinH/xhprof/archive/v2.1.0.tar.gz
mv v2.1.0.tar.gz xhprof.tar.gz
tar -zxvf xhprof.tar.gz
# 进入需要编译的文件夹
cd /var/www/xhprof/extension
#侦测环境、配置、编译、安装
phpize
./configure
make
make install
安装成功后,在php.ini文件中加入 xhprof 的相关配置
[XHPROF]
extension=xhprof.so
xhprof.output_dir=/var/www/xhprof_output
其中 xhprof.output_dir 用于配置 xhprof 分析文件的输出目录。
配置完成后,重启php服务
安装画图相关扩展
libpng
wget https://github.com/glennrp/libpng/archive/v1.6.35.tar.gz
mv v1.6.35.tar.gz libpng-1.6.35.tar.gz
tar -zxvf libpng-1.6.35.tar.gz
cd libpng-1.6.35
./configure
make
make install
graphviz
apt-get install -y graphviz
graphviz 用于生成图形化分析结果
配置 xhprof 图形界面访问地址
xhprof 的分析结果有图形界面可以查看,我们需要配置nginx代理来使用这个图形界面。
配置nginx,将目录指向 /var/www/xhprof/xhprof_html/ 即可。一下配置可用于参考:
server {
listen 80;
server_name loc.xhprof.com;
root /var/www/xhprof/xhprof_html/;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_pass php-upstream;
fastcgi_index index.php;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fixes timeouts
fastcgi_read_timeout 600;
include fastcgi_params;
}
access_log /var/log/nginx/xhprof/access.log;
error_log /var/log/nginx/xhprof/error.log;
}
本地dns解析(hosts 文件)加上对应的配置
127.0.0.1 loc.xhprof.com
重启 nginx 服务
现在通过访问 loc.xhprof.com 就能看到分析结果,页面会将 /var/www/xhprof_output 中的文件以列表方式展示出来。不过我们现在还没做任何的代码分析,所以现在访问这个地址我们暂时看不到任何结果。
使用 xhprof 分析代码性能
加入数据采集代码
在需要做性能分析的代码段前后,引入xhprof相关代码。
save_run($xhprofData, 'xhprof_testing');
上面代码中引入的两个文件都存在于在安装步骤中 xhprof 目录下。
xhprof_enable() 可以通过传参来设置采集维度:
参数 | 说明 |
---|---|
XHPROF_FLAGS_NO_BUILTINS | 使得跳过所有内置(内部)函数 |
XHPROF_FLAGS_CPU | 使输出的性能数据中添加 CPU 数据 |
XHPROF_FLAGS_MEMORY | 使输出的性能数据中添加内存数据 |
xhprof_disable() 返回每个方法的监控数据,输出返回结果可以看到类似的结构:
[方法名] => Array
(
[ct] => 1 // 方法被调用的次数
[wt] => 419 // 方法耗时,单位(微秒)
[cpu] => 0 // 消耗CPU时间,单位(微秒)
[mu] => 8264 // 内存使用情况,单位(bytes)
[pmu] => 0 // 使用内存峰值,单位(bytes)
)
xhprof_disable() 的返回结果只能得到每个方法的一些数据,如果我们自己对这个结果做分析的话工作量还是很庞大的。后面我们用到 xhprof 自带的图形界面能更直观的看出我们代码的问题。
XHProfRuns_Default类内的save_run方法,第二个参数传项目名。这个方法以 "采集ID.项目名.xhprof " 构成的文件名将采集结果保存到 /var/www/xhprof_output 中。
在执行完代码后,通过访问 xhprof 图形界面访问地址,可以看到这次的分析结果。
分析结果说明
下面说明一下页面表格中的相关数据表示
Incl. Including的缩写,表示包含子函数的消耗
Excl. Excluding的缩写,表示不包含子函数的消耗
Calls: 方法被调用的次数
Calls%: 方法被调用次数占总被调用次数的百分比
Incl.Wall Time: 函数本身加上子函数的运行时间
IWall%: 函数本身加上子函数的运行时间占总运行时间的百分比
Excl.Wall Time: 函数的运行时间
EWall%: 函数的运行时间占总运行时间的百分比
假如开了CPU监控、内存监控,会有下面这几个数据
Incl.CPU: 函数本身加上子函数执行花费的CPU时间
ICPU%: 函数本身加上子函数执行花费的CPU时间占总时间的百分比
Excl.CPU: 函数本身执行花费的CPU时间
ECPU%: 函数本身执行花费的CPU时间占总时间的百分比
Incl.MemUse: 函数本身加上子函数占用的内存(单位:字节)
IMemUse%: 函数本身加上子函数占用的内存占总使用内存的百分比
Excl.MemUse: 函数本身占用的内存(单位:字节)
EMemUse%: 函数本身占用的内存占总使用内存的百分比
Incl.PeakMemUse: 函数本身加上子函数占用内存的峰值(单位:字节)
Excl.PeakMemUse: 函数本身占用内存的峰值(单位:字节)
上面的表格已经是一个比较直观的数据了,xhprof还支持图形化的结果。
在使用图形化结果之前,需要系统先安装 graphviz。graphviz 是用来根据 xhprof 的结果绘制分析图的。
点击上面结果页面中部的 [View Full Callgraph] 就能自动跳转到图形结果界面。