「PHP」- XHProf

  CREATED BY JENKINSBOT

XHProf,由Facebook开源出的PHP程序性能分析工具。

XHProf简介

在数据收集阶段,它跟踪调用次数与测量数据,展示程序动态调用的弧线图。 它在报告、后期处理阶段计算了独占的性能度量,例如运行经过的时间、CPU 计算时间和内存开销。 函数性能报告可以由调用者和被调用者终止。 在数据搜集阶段 XHProf 通过调用图的循环来检测递归函数,通过赋予唯一的深度名称来避免递归调用的循环。

XHProf Web界面:XHProf 包含了一个基于 HTML 的简单用户界面(由 PHP 写成)。 基于浏览器的用户界面使得浏览、分享性能数据结果更加简单方便。

调用图:XHProf 的报告对理解代码执行结构常常很有帮助。 比如此分层报告可用于确定在哪个调用链里调用了某个函数,支持查看调用图。

结果数据处理及分析:XHProf 对两次运行进行比较(又名 “diff” 报告),或者多次运行数据的合计。 对比、合并报告,很像针对单次运行的“平式视图”性能报告,就像“分层式视图”的性能报告。

如何安装并配置XHProf扩展?

安装依赖
XHProf插件本身没有特别依赖什么。但是收集到的数据是通过PHP开发的Web界面来显示的,所以需要安装Web环境

Github上还有一个带GUI的XHProf分支,可以到Github上下载这个分支

安装XHProf扩展
可以到PCEL中下载XHProf,然后使用phpize手动安装;
或者使用PCEL安装扩展。这里使用pecl命令直接安装:

#!/bin/sh

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
重启PHP-FPM之后,检查XHProf是否加载进来。

在程序中,使用XHProf API来采集数据

项目里使用了三个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_disable — 停止 xhprof 性能采样分析器
xhprof_sample_enable — 以采样模式启动 XHProf 性能分析

$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 List

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

更新日志

06/22/2017 修正prepend.php中的BUG。