XHProf是facebook开源出来的一个PHP轻量级的性能分析工具,跟Xdebug类似,但性能开销更低,还可以用在生产环境中,也可以由程序开关来控制是否进行profile。

安装

  • macOS

    brew search xhprof
    brew install php56-xhprof
    
  • 编译

    wget http://pecl.php.net/get/xhprof-0.9.4.tgz
    tar -zxvf xhprof-0.9.4.tgz 
    cd xhprof-0.9.4
    cd extension/
    phpize
    ./configure
    make
    sudo make install
    
    [xhprof]
    extension=xhprof.so
    xhprof.output_dir=/tmp
    
  • 依赖

    可视化分析图功能需要安装graphviz库,否则会报如下错误:

    failed to execute cmd: " dot -Tpng". stderr: `sh: dot: command not found '

    yum install graphvizbrew install graphviz进行安装

使用

开启性能分析

void xhprof_enable ([ int $flags = 0 [, array $options ]] )

  • flags 该参数用于为剖析结果添加额外的信息,该参数的值使用以下宏,如果需要提供多个值,使用|进行分隔。

    • XHPROF_FLAGS_NO_BUILTINS 跳过所有的内置函数

    • XHPROF_FLAGS_CPU 添加对CPU使用的分析

    • XHPROF_FLAGS_MEMORY 添加对内存使用的分析

  • options 数组形式提供可选参数,在此处提供ignored_functions选项需要忽略的函数

结束性能分析

array xhprof_disable ( void )

示例代码

xhprof源码包下的xhprof_libxhprof_html拷贝到项目目录下

<?php

// 开启xhprof
xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU, []);

// 在程序结束后收集数据
register_shutdown_function(function () {
    // 关闭xhprof
    $xhprof_data = xhprof_disable();
    
    // 冲刷(flush)所有响应的数据给客户端
    if (function_exists('fastcgi_finish_request')) {
        fastcgi_finish_request();
    }

    // 保存xhprof分析数据
    include_once 'xhprof/xhprof_lib/utils/xhprof_lib.php';
    include_once 'xhprof/xhprof_lib/utils/xhprof_runs.php';
    $xhprof_runs = new XHProfRuns_Default();
    $run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");
});

// 接下来就是正常的业务代码
// ...

但是这样免不了要修改项目的源代码,其实php本身就提供了更好的注入方式,比如将上述逻辑保存为/opt/inject.php,然后修改php.ini配置文件

auto_prepend_file = /opt/inject.php

这样所有的php-fpm请求的php文件前都会自动注入/opt/inject.php文件

如果使用Nginx的话,还可以通过Nginx的配置文件设置,这样侵入性更小,并且可以实现基于站点的注入。

fastcgi_param PHP_VALUE "auto_prepend_file=/opt/inject.php";

浏览器中访问xhprof_html目录下的index.php路径,就可以看到所有访问页面的分析数据:

点击其中一条数据的链接,会看到整个访问的详细分析数据:

我们可以在分析页面中看到包含内置函数、CPU、内存、调用次数、执行顺序等相关的信息,以及整个 PHP 程序周期内的所有链路信息。

点击[View Full Callgraph],则会展示一张程序执行堆栈图:

堆栈图中,最粗的那条主线代表了耗用资源最多的地方,值得我们关注和分析是否在这些地方存在这性能问题。标红的部分则表明性能比较低下。 (注意:如果没法展示堆栈图,说明没安装graphviz

参考资料