安装
git clone https://github.com/phacility/xhprof.git
cd xhprof/extension
phpize
./configure --with-php-conf=/usr/local/php/bin/php-config
make && make install
将xhprof.so加入到php.ini
重启php-fpm
可以使用kill -USR2 pid(php-fpm master进程的pid)平滑重启
设置XHProf UI
前提:在项目中引入xhprof_lib/utils/
下的xhprof_lib.php
和xhprof_runs.php
,在这里我的做法是把xhprof_lib
目录拷贝到项目中去(自行参考),如下示例:
function test(){
ini_set('xhprof.output_dir','/usr/local/php/tmp/xhprof'); //设置xhprof生成的文件目录,可在php.ini永久设置
xhprof_enable(); //启动 xhprof 性能分析器
$a = ['aa']; //业务代码
$data = xhprof_disable(); //停止性能分析,并返回此次运行的 xhprof 数据。
include_once \Yii::$app->getBasePath().'/web/xhprof_lib/utils/xhprof_lib.php';
include_once \Yii::$app->getBasePath().'/web/xhprof_lib/utils/xhprof_runs.php';
$xhprof_runs = new \XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($data,'xhprof_one');
echo "<a href='http://localhost:81/index.php?run=".$run_id."&source;=xhprof_one'>xhprof</a>";
}
test();
运行完成以后,会在xhprof.output_dir=/usr/local/php/tmp/xhprof
下生成相应的数据文件,然后使用http://localhost/index.php访问,如图所示
image.png
image.png
http://localhost/index.php是什么呢?是xhprof下xhprof_html目录,需要配置nginx可访问
第三张图是点击第二张图里的View Full Callgraph
显示
这个图显示,需要graphviz
支持
如没有安装会报failed to execute cmd: " dot -Tpng". stderr: sh: dot: command not found
如还未成功,那就看dot
位于系统的什么命令目录下,如:/usr/local/bin
再去看xhprof_lib/utils/callgraph_utils.php
里xhprof_generate_image_by_dot
方法有如下一行代码
$process = proc_open( $cmd, $descriptorspec, $pipes, sys_get_temp_dir(), array( 'PATH' => getenv( 'PATH' )) );
这里的getenv( 'PATH' ) 输出为:/usr/bin:/bin:/usr/sbin:/sbin
,没有包含系统dot
命令目录
修改这行代码
$process = proc_open( $cmd, $descriptorspec, $pipes, sys_get_temp_dir(), array( 'PATH' => getenv( 'PATH' ).':/usr/local/bin' ) );
function xhprof_generate_image_by_dot($dot_script, $type) {
$descriptorspec = array(
// stdin is a pipe that the child will read from
0 => array("pipe", "r"),
// stdout is a pipe that the child will write to
1 => array("pipe", "w"),
// stderr is a pipe that the child will write to
2 => array("pipe", "w")
);
$cmd = " dot -T".$type;
$process = proc_open( $cmd, $descriptorspec, $pipes, sys_get_temp_dir(), array( 'PATH' => getenv( 'PATH' ).':/usr/local/bin' ) );
if (is_resource($process)) {
fwrite($pipes[0], $dot_script);
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
$err = stream_get_contents($pipes[2]);
if (!empty($err)) {
print "failed to execute cmd: \"$cmd\". stderr: `$err'\n";
exit;
}
fclose($pipes[2]);
fclose($pipes[1]);
proc_close($process);
return $output;
}
print "failed to execute cmd \"$cmd\"";
exit();
}
第一次写技术类文章,杂乱无序,希望能帮到你
参考资料:
http://www.cleey.com/blog/single/id/818.html
http://web.archive.org/web/20110514095512/http://mirror.facebook.net/facebook/xhprof/doc.html#credits
网友评论