服务器端编程-XHProf

介绍
xhprof是Facebook开源的轻量级PHP性能分析工具,Linux环境下可以通过pecl直接安装

安装

pecl install xhprof-beta
echo "extension=xhprof.so" > /etc/php5/fpm/conf.d/xhprof.ini
service php5-fpm restart

之后可以通过phpinfo()检查扩展是否已经加载。

使用
xhprof项目中已经提供了示例以及简易的UI,下载xhprof项目到web服务器,
假设可以通过访问 http://localhost/xhprof/
那么访问 http://localhost/xhprof/examples/sample.php可以看到一些输出,
并且提示通过访问http:///index.php?run=XXX&source=xhprof_foo查看结果。
接下来访问http://localhost/xhprof/xhprof_html/
就可以看到已经保存的结果,列出了所有函数的调用以及所消耗的时间。
分析一下示例代码sample.php,关键部分只有2行:

//开启xhprof并开始记录
xhprof_enable();
//运行一些函数
foo();
//停止记录并取到结果
$xhprof_data = xhprof_disable();

$xhprof_data中记录了程序单步运行过程中所有的函数调用时间及CPU内存消耗等,具体记录哪些指标可以通过xhprof_enable控制,之后的处理已经与xhprof扩展无关,大致是编写了一个存储类XHProfRuns_Default,将$xhprof_data序列化并保存到某个目录,可以通过XHProfRuns_Default(__DIR__)将结果输出到当前目录,如果不指定则会读取php.ini配置文件中xhprof.output_dir,仍然没有指定则会输出到/tmp
xhprof_html/index.php。

将记录的结果整理并可视化,默认的UI里列出了

1. funciton name : 函数名
2. calls: 调用次数
3. Incl. Wall Time (microsec): 函数运行时间(包括子函数)
4. IWall%:函数运行时间(包括子函数)占比
5. Excl. Wall Time(microsec):函数运行时间(不包括子函数)
6. EWall%:函数运行时间(不包括子函数)

每一项应该不难理解,以项目自带的sample.php为例,示例中编写了一个main()函数,main()函数中调用foo()bar()等一些子函数进行了一点字符处理。整个程序运行过程中,main()函数只运行了一次,并且由于main()函数中包括了所有的逻辑,所以main()函数的IWall%占比为100%,但是由于main()函数的功能都是由子函数实现的,因此main()函数的EWall%只有0.3%,而foo()函数完成了主要的工作,EWall%有98.1%。因此在分析更大型的程序时,往往需要根据这几项指标分别排序,从不同的角度审视性能消耗。

xhprof_html/index.php中还可以看到View Full Callgraph链接,点击后可以绘制出一张可视化的性能分析图,如果点击后报错的话,可能是缺少依赖graphviz,ubuntu可以通过apt安装

apt-get install graphviz

更好的注入方式
了解了上面这些,其实就已经可以将xhprof整合到任何我们已有的项目中去了。目前大部分MVC框架都有唯一的入口文件,只需要在入口文件的开始处注入xhprof的逻辑

//开启xhprof
xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU);
//在程序结束后收集数据
register_shutdown_function(function() {
    $xhprof_data        = xhprof_disable();

    //让数据收集程序在后台运行
    if (function_exists('fastcgi_finish_request')) {
        fastcgi_finish_request();
    }

    //保存xhprof数据
    ...
});

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

vi /etc/php5/fpm/php.ini

修改auto_prepend_file配置

auto_prepend_file = /opt/inject.php

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

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

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

更好的图形化展示结果见: http://avnpc.com/pages/profiler-php-performance-online-by-xhprof
源码安装xhprof:https://segmentfault.com/a/1190000003509917

你可能感兴趣的:(服务器端编程-XHProf)