问题描述
XHProf,由 Facebook 开源出的 PHP 程序性能分析工具。
在数据收集阶段,它跟踪调用次数与测量数据,展示程序动态调用的弧线图。 它在报告、后期处理阶段计算了独占的性能度量,例如运行经过的时间、CPU 计算时间和内存开销。 函数性能报告可以由调用者和被调用者终止。 在数据搜集阶段 XHProf 通过调用图的循环来检测递归函数,通过赋予唯一的深度名称来避免递归调用的循环。
XHProf Web界面:XHProf 包含基于 HTML 的简单用户界面(由 PHP 写成)。 基于浏览器的用户界面使得浏览、分享性能数据结果更加简单方便。
调用图:XHProf 的报告对理解代码执行结构常常很有帮助。 比如此分层报告可用于确定在哪个调用链里调用了某个函数,支持查看调用图。
结果数据处理及分析:XHProf 对两次运行进行比较(又名 “diff” 报告),或者多次运行数据的合计。 对比、合并报告,很像针对单次运行的“平式视图”性能报告,就像“分层式视图”的性能报告。
解决方案
第一步、安装扩展
安装依赖
XHProf 插件本身无过多依赖。但是收集到的数据是通过PHP开发的Web界面来显示的,所以需要安装Web环境。
Github上还有一个带GUI的XHProf分支,可以到Github上下载这个分支
安装扩展
可以到PCEL中下载XHProf,然后使用phpize手动安装;
或者使用PCEL安装扩展。这里使用pecl命令直接安装:
pecl search xhprof # 根据输出,执行: pecl install xhprof-0.9.4
修改 php.ini 文件,启用扩展,并配置相依的参数:
[xhprof] ;; 启动扩展 extension=xhprof.so ;; 由xhprof收集的数据的保存目录。 xhprof.output_dir="/path/to/output/dir"
重启 PHP-FPM 服务,检查XHProf是否加载进来。
第二步、采集数据
项目里使用了三个PHP框架,站点比较多,不能挨个添加;而且随处都有exit(),这就导致xhprof_disable()函数无法执行。所以采用如下解决办法:
使用php.ini中的auto_prepend_file变量,并且使用register_shutdown_function函数。
创建prepend.php
内容如下:
<?php mxhprof_start(); register_shutdown_function(mxhprof_shutdown); function mxhprof_start(){ // xhprof_enable(XHPROF_FLAGS_NO_BUILTINS & XHPROF_FLAGS_CPU & XHPROF_FLAGS_MEMORY); xhprof_enable(XHPROF_FLAGS_NO_BUILTINS | XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY); } function mxhprof_shutdown(){ $xhprof_data = xhprof_disable(); include '/path/to/xhprof_lib/utils/xhprof_lib.php'; include '/path/to/xhprof_lib/utils/xhprof_runs.php'; $xhprof_runs = new XHProfRuns_Default(); // 注意文件名中不能有`.',而主机名中带有`.',所以修改后的代码如下: // $run_id = $xhprof_runs->save_run($xhprof_data, $_SERVER['HTTP_HOST']); $compHost = str_replace('.', '_', $_SERVER['HTTP_HOST']); $run_id = $xhprof_runs->save_run($xhprof_data, $compHost); }
修改php.ini,引入prepend.php文件
在php.ini中加入如下内容:
auto_prepend_file=/home/data/wwwroot/profiling/extend/prepend.php
接下来,访问站点就可以了,分析的记过会自动输出到xhprof.output_dir指定的目录中。
查看XHProf生成的数据
安装Graphviz
生成的逻辑图文件是DOT语言,所以需要安装Graphviz,参考另外一篇文章:「Graphviz安装」
XHProf Web界面
安装XHProf Web界面,用于查看生成的数据。源码位于XHProf源码目录/xhprof_html,像配置Web站点一样就可以了,没有什么特别的地方。
相关函数及常量
在 XHProf 中,共计四个函数
// 停止 xhprof 分析器 xhprof_disable // 启动 xhprof 性能分析器 void xhprof_enable ([ int $flags = 0 [, array $options ]] ) // 以采样模式启动 XHProf 性能分析 xhprof_sample_enable // 停止 xhprof 性能采样分析器 xhprof_sample_disable
$flags的取值为:
XHPROF_FLAGS_NO_BUILTINS (integer) Used to skip all built-in (internal) functions. XHPROF_FLAGS_CPU (integer) Used to add CPU profiling information to the output. XHPROF_FLAGS_MEMORY (integer) Used to add memory profiling information to the output.
更多内容参考php.net中的XHProf手册,或者参考XHProf官方手册。
常见问题处理
Error: either we can not find profile data for run_id 5949d5ca2851b or the threshold 0.01 is too small or you do not have ‘dot’ image generation utility installed.
导致这个问题的原因有很多,错误提示的位置位于:xhprof_lib/utils/callgraph_utils.php
我是通过代码调试,发现最终在:xhprof_lib/utils/xhprof_runs.php->get_run()中生成的file_name不对,最后半猜半蒙感觉是文件名中不能有点号(.)。
解决:修改生成文件的名字,启动名字中的点号(.)。
参考文献
PHP.NET / Xhprof
Facebook / XHProf Documentation
CSDN/php xingnengfenxi_PHP性能分析工具xhprof