php轻量级的性能分析工具xhprof的安装使用


Posted in PHP onAugust 12, 2015

一、前言

有用的东西还是记录下来吧,也方便以后的查询;这次记录一下xhprof的安装使用;

xhprof是facebook开源出来的一个php轻量级的性能分析工具,跟Xdebug类似,但性能开销更低,

还可以用在生产环境中,也可以由程序开 关来控制是否进行profile。

二、安装

wget http://pecl.php.net/get/xhprof-0.9.3.tgz 
  tar zxf xhprof-0.9.3.tgz 
  cd xhprof-0.9.3/extension
  /usr/bin/phpize 
 (php版本安装后生成的phpize文件,可根据phpinfo查看,所以php版本不同,生成的phpize也不同,此步骤主要生成configure文件)
  ./configure ?with-php-config=/usr/bin/php-config 
 (php-config的路径,也是php安装后生成的文件) 
  make 
  sudo make install

 (会自动将生成的扩展文件拷贝到扩展目录中/usr/lib64/php/modules)

    当然具体的php文件的目录,每个人不尽相同,可根据phpinfo查询

三、php.ini配置

根据phpinfo找到 extension_dir的目录
(/etc/php.d/xhprof.ini)

添加一下内容:

extension=xhprof.so
xhprof.output_dir=/tmp/xhprof //xhprof的分析日志

四、重启服务

sudo /etc/init.d/http restart

 查看phpinfo是否安装成功

五、使用方法

开头:
xhprof_enable(); //开启监测 
//xhprof_enable(XHPROF_FLAGS_NO_BUILTINS); 不记录内置的函数 
//xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY); 同时分析CPU和Mem的开销 

//要测试的代码
...
...
...

结尾:
$xhprof_data = xhprof_disable(); //停止监测,返回运行数据
$xhprof_root = '/(xhprof的虚拟主机目录)/'; 
 //引入当初安装到xhprof虚拟主机目录中的文件
include_once $xhprof_root."xhprof_lib/utils/xhprof_lib.php"; 
include_once $xhprof_root."xhprof_lib/utils/xhprof_runs.php";  
$xhprof_runs = new XHProfRuns_Default();  
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof");
echo '<a href="http://(xhprof的虚拟主机域名)/xhprof_html/index.php?run='.$run_id.'&source=xhprof" target="_blank">xhprof统计</a>';

上边的代码使用了,给xhprof设置虚拟主机的方法。

把源码包中的 xhprof_html 和 xhprof_lib 文件夹拷贝到自己建立的虚拟目录中

cp -r xhprof_html xhprof_lib /xxx/xhprof/  (此处目的是建立数据分析目录,可将此目录配置成虚拟主机访问)

运行后,统计点击返回的 xhprof统计 链接,即可。

六、注意问题以及名词解释

在显示的统计页面中,点[View Full Callgraph]图形化显示(最大的性能问题会用红色标出,其次是黄色);

点击后,可能提示错误消息,执行以下命令即可

yum install -y graphviz
 yum install graphviz-gd

名词解释

 

Function Name 函数名
 Calls 调用次数
 Calls% 调用百分比
 Incl. Wall Time (microsec) 调用的包括子函数所有花费时间 以微秒算(一百万分之一秒)
 IWall% 调用的包括子函数所有花费时间的百分比
 Excl. Wall Time (microsec) 函数执行本身花费的时间,不包括子树执行时间,以微秒算(一百万分之一秒)
 EWall% 函数执行本身花费的时间的百分比,不包括子树执行时间
 Incl. CPU(microsecs) 调用的包括子函数所有花费的cpu时间。减Incl. Wall Time即为等待cpu的时间
 减Excl. Wall Time即为等待cpu的时间
 ICpu% Incl. CPU(microsecs)的百分比
 Excl. CPU(microsec) 函数执行本身花费的cpu时间,不包括子树执行时间,以微秒算(一百万分之一秒)。
 ECPU% Excl. CPU(microsec)的百分比
 Incl.MemUse(bytes) 包括子函数执行使用的内存。
 IMemUse% Incl.MemUse(bytes)的百分比
 Excl.MemUse(bytes) 函数执行本身内存,以字节算
 EMemUse% Excl.MemUse(bytes)的百分比
 Incl.PeakMemUse(bytes) Incl.MemUse的峰值
 IPeakMemUse% Incl.PeakMemUse(bytes) 的峰值百分比
 Excl.PeakMemUse(bytes) Excl.MemUse的峰值
 EPeakMemUse% EMemUse% 峰值百分比

xhprof的安装与简易用法

xhprof是Facebook开源的轻量级PHP性能分析工具,Linux环境下可以通过pecl直接安装,比如在Ubuntu下仅需3行指令

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://<xhprof-ui-address>/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里列出了:
•funciton name : 函数名
•calls: 调用次数
•Incl. Wall Time (microsec): 函数运行时间(包括子函数)
•IWall%:函数运行时间(包括子函数)占比
•Excl. Wall Time(microsec):函数运行时间(不包括子函数)
•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";
PHP 相关文章推荐
php环境配置 php5 mysql5 apache2 phpmyadmin安装与配置
Nov 17 PHP
一周让你学会PHP 不错的学习资料
Feb 06 PHP
网页上facebook分享功能具体实现
Jan 26 PHP
php定义参数数量可变的函数用法实例
Mar 16 PHP
PHP SPL标准库之数据结构堆(SplHeap)简单使用实例
May 12 PHP
PHP中的类型提示(type hinting)功能介绍
Jul 01 PHP
详解php的socket通信
Aug 11 PHP
汇总PHPmailer群发Gmail的常见问题
Feb 24 PHP
PDO的安全处理与事物处理方法
Oct 31 PHP
PHP针对中英文混合字符串长度判断及截取方法示例
Mar 31 PHP
PHP实现生成模糊图片的方法示例
Dec 21 PHP
浅谈laravel框架sql中groupBy之后排序的问题
Oct 17 PHP
详细解读PHP中接口的应用
Aug 12 #PHP
举例讲解PHP面对对象编程的多态
Aug 12 #PHP
详解PHP中的状态模式编程
Aug 11 #PHP
简单介绍PHP的责任链编程模式
Aug 11 #PHP
PHP会话处理的10个函数
Aug 11 #PHP
PHP的Socket网络编程入门指引
Aug 11 #PHP
php实现的农历算法实例
Aug 11 #PHP
You might like
php初始化对象和析构函数的简单实例
2014/03/11 PHP
PHP抽象类和接口用法实例详解
2019/07/20 PHP
js实现鼠标感应图片展示的方法
2015/02/27 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
Bootstrap入门书籍之(五)导航条、分页导航
2016/02/17 Javascript
jQuery轮播图效果精简版完整示例
2016/09/04 Javascript
深入探讨Vue.js组件和组件通信
2016/09/12 Javascript
Bootstrap页面标题Page Header的实现方法
2017/03/22 Javascript
JavaScript 中Date对象的格式化代码方法汇总
2017/09/06 Javascript
vue 之 .sync 修饰符示例详解
2018/04/21 Javascript
如何使用 vue + d3 画一棵树
2018/12/03 Javascript
微信小程序实现发送验证码按钮效果
2018/12/20 Javascript
layui内置模块layim发送图片添加加载动画的方法
2019/09/23 Javascript
jQuery实现弹幕特效
2019/11/29 jQuery
ES6的异步操作之promise用法和async函数的具体使用
2019/12/06 Javascript
javascript实现贪吃蛇小游戏
2020/07/28 Javascript
JavaScript构造函数原理及实现流程解析
2020/11/19 Javascript
[02:16]卖萌的僵尸 DOTA2神话信使飞僵小宝来袭
2014/03/24 DOTA
[08:54]《一刀刀一天》之DOTA全时刻18:十九支奔赴西雅图队伍全部出炉
2014/06/04 DOTA
[02:29]大剑、皮鞭、女装,这届DOTA2勇士令状里都有
2020/07/17 DOTA
Python远程桌面协议RDPY安装使用介绍
2015/04/15 Python
详解Python的Django框架中的模版相关知识
2015/07/15 Python
Python的Flask框架的简介和安装方法
2015/11/13 Python
Python实现的插入排序算法原理与用法实例分析
2017/11/22 Python
解决python3 requests headers参数不能有中文的问题
2019/08/21 Python
详解Flask前后端分离项目案例
2020/07/24 Python
Python如何读写字节数据
2020/08/05 Python
Python本地及虚拟解释器配置过程解析
2020/10/13 Python
Python爬取网站图片并保存的实现示例
2021/02/26 Python
Vision Direct比利时:在线订购隐形眼镜
2019/08/27 全球购物
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
小学教学随笔感言
2014/02/26 职场文书
公务员诚信承诺书
2014/05/26 职场文书
2014年司法所工作总结
2014/11/22 职场文书
2019幼儿园感恩节活动策划书
2019/11/28 职场文书
Vue OpenLayer测距功能的实现
2022/04/20 Vue.js