210 likes | 421 Vues
微游戏技术分享之 XHPorf PHP 性能分析工具 Mercedes+ 2013.04.01 chen.chen@weiyouxi.com http://notech.net. What is it?. XHProf is a function-level hierarchical profiler for PHP and has a simple HTML based user interface . 一个函数级别的分层 PHP 性能分析工具 以及一个简单的 web 版的用户界面 由 PHP 界顶梁柱 Facebook 友情开源提供.
E N D
微游戏技术分享之XHPorfPHP性能分析工具 Mercedes+ 2013.04.01chen.chen@weiyouxi.comhttp://notech.net
What is it? XHProf is a function-level hierarchical profiler for PHP and has a simple HTML based user interface. 一个函数级别的分层PHP性能分析工具 以及一个简单的web版的用户界面 由PHP界顶梁柱Facebook友情开源提供 From:https://github.com/facebook/xhprof#readme
What can it do? XHProf可以报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。 并且一个函数的开销,可细分成调用者和被调用者的开销。 原始数据收集部分是用纯C实现的,是一个名叫xhprof的 Zend扩展 。 除此之外XHProf还有一个简单的HTML的用户界面( PHP写成的)。 XHProf报告往往可以有助于理解被执行的代码的结构。 它生成的callgraph图像简直就是逆天级别的玩意,是我用过的最好用的PHP工具之一. 毫不夸张的说, 秒xdebug的profiler日志好几条街没有一点问题! 详细对比的演示.参见:http://notech.net/565.cc
XHProf特点 扁平的性能概要
XHProf特点 分层剖析
XHProf特点 差异化报告
XHProf特点 Callgraph视图
一些细节 术语表 Inclusive Time (或子树执行时间) :[包括子树执行时间的所有执行时间。] Exclusive Time/Self Time :[函数执行本身的时间花费。]不包括子树执行时间。 Wall时间 :又名经过的时间或挂钟时间。 CPU时间 : CPU时间在用户空间+ CPU时间在内核空间 • 特殊函数的命名约定 • main():一个虚构的函数,这是所有调用的根节点。 • load::<filename> 和 run_init::<filename>:XHProf跟踪PHP的include/require操作,和跟踪函数调用一样。 • 例如, include “lib/common.php";操作看起来像调了两个XHProf函数: • load::lib/common.php - 内核加载和编译文件的工作。 • [注:如果您使用的了PHP的opcode缓存比如APC之类的,只有当缓存失效时才会去编译。 • run_init::lib/common.php -由于包含操作引起的初始化操作等。 • foo@<n>:意味着这是一个foo()函数的递归调用。<n>代表递归深度。 • 递归可能是直接的,(比如由于foo() --> foo() ) ,也可能是间接的(如由于foo()-> goo() ->foo()。 局限 真正的层次剖析器会在每一个数据采集点记录完全的调用堆栈。 如果能够做到这一步我们就可以回答某些问题,比如说:我想知道第三次foo()调用的开销是多少? 或是当调用栈是a()->b()->bar()时bar()函数的开销是多少? XHProf只记录一级的调用上下文,因此只能回答关于一级一级函数调用的问题。事实证明,在实践中这是最主要的利用情况。
继续,局限性 关于后续更新 Xhprof最新的版本是0.9.2,下图是pecl官网的截图,可以看出,最新的版本还挂着beta标签,并且是4年前的东西了. 我下载了xhprof的最新源码,然后看到了一些东西: Rdtsc大概是个cpu指令集,(Time Stamp Counter) 获取时间用的.我专门搜索了这货的信息,发现使用RDTSC指令的话, 在现今的硬件环境中精确度会有折扣.而且在使用了speedstep技术的CPU上会出现问题.例如:省略 解决的途径:在 Windows 用 QueryPerformanceCounter Linux 下用 POSIX 的 clock_gettime函数等.
安装实施 Google一下你就知道,这里不再浪费大家时间 也可以参考这里:http://notech.net/410.cc
使用 $php-dextension=xhprof.so foo.php
使用 以上上微游戏主站的xhprof方式,亮哥完成的,大家可以直接在不同的业务项目中直接使用.前提是已经安装了相应扩展
使用 $xhprof_data = xhprof_disable(); include_once'/home/huliang/www/xhprof/xhprof_lib/utils/xhprof_lib.php'; include_once'/home/huliang/www/xhprof/xhprof_lib/utils/xhprof_runs.php'; $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run( $xhprof_data , CON . "_" . METHOD); // 该域名配置在 211 上 $xhprof_url = "http://xhprof.test.game.weibo.com/index.php?run=" . $run_id . "&source=" . CON . "_" . METHOD ; 这里有几点说明: 1.save的目录是在ini配置文件中的目录:xhprof.output_dir = /xxx/xxx 2.Save函数的第二个参数,是命名空间防止混乱,这里使用的是控制器+方法名作的命名空间 3.关于访问地址的说明: 一)看单一运行报告 要查看run id是<run_id>和命名空间是<namespace>的报告,访问URL: http://<xhprof-ui-address>/index.php?run=<run_id>&source=<namespace> 例如, http://<xhprof-ui-address>/index.php?run=49bafaa3a3f66&source=xhprof_foo 二)查看diff报告 要查看命名空间<namespace>下runid分别是< run_id1>和<run_id2>的两个报告,访问URL: http://<xhprof-ui-address>/index.php?run1=<run_id1>&run2=<run_id2>&source=<namespace> 三)汇总报告 您也可以指定一组run id来汇总得到您想要的报告视图。 如果你有三个XHProf运行,都在"benchmark‘命名空间下,run id分别是1,2,3。要查看这些运行的汇总报告: http://<xhprof-ui-address>/index.php?run=1,2,3&source=benchmark 加权汇总 :进一步假设,上述3个运特分别对应三种程序,p1.php,p2.php和p3.php ,通常以20%,30%,50%概率混合:要查看汇总报告所对应的加权平均数这些运行使用: http://<xhprof-ui-address>/index.php?run=1,2,3&wts=20,30,50&source=benchmark
一些体会 首先我们应该大概了解了xhprof的工作流程,就是在程序开始的时候开启xhprof以收集php运行时的信息,然后在disable 的时候保存这些信息成profiler日志文件,然后自带的工具可以根据相应的文件生成报告和callgraph图像. 那么这里就会出现一个问题:随着时间的推移,日志文件会越来越多,那么管理起来就非常不方便了. 这里我们可以修改$filename参数来控制日志生成的名字,这样从某种程度上便于我们区分管理. 但是我们还是不知道对应的url生成的对应的日志文件是什么. 所以我们可以改造亮哥的代码: 这里我把相应的SERVER信息保存了下来,并写入了一个文件,这个文件和日志是一一对应关系.这样我们就可以通过管理这些文件来管理日志了.