php的性能分析工具:xhprof

本篇博文所使用的环境如下:

PHP版本:php7.2

操作系统环境:CentOS Linux release 7.7.1908 (Core)

前言概述

你和别人同时写出了一个导出用户的功能,你的导出一次用了20分钟,而别人的导出用户功能只用了1分钟,那么这里就很明显的区分出来了你们代码的效率。代码的优劣是问题的根源。如果你想找出是什么原因导致代码执行这么慢,那么你就要学会怎么分析代码性能,找到代码瓶颈。


我们除了可以使用xdebug分析php的性能之外,还可以使用xhprof进行分析php的代码性能。

xhprof工具的简介

xhprof是由facebook开源出来的一个php轻量级的性能分析工具,跟xdebug类似,但性能开销更低,还可以用在生产环境中,也可以由程序开关来控制是否进行profile。但是官方因为长时间不更新,针对php7已无法正常安装使用。


对于还在使用php5的童鞋,可以到php官方进行下载安装:

https://pecl.php.net/package/xhprof


php7系列的xhprof扩展可以在以下地址进行下载安装: 

https://github.com/longxinH/xhprof  // xhprof的开源地址(这是第三方的一个库,并不是xhprof官方的。xhprof官方暂不支持php7系列)

xhprof版本下载地址:https://github.com/longxinH/xhprof/releases

xhprof安装

 wget https://github.com/longxinH/xhprof/archive/v2.1.0.tar.gz
 
 tar -zxvf v2.1.0.tar.gz
 
 cd xhprof-2.1.0/
 
 cd extension/
 phpize
 
 ./configure --with-php-config=/usr/bin/php-config #这里的php-config路径换成你自己的
 
 make && make install
 
 #ps:如果你wget不下来,文件末尾我会给出相关文件的,自行下载并上传到自己的服务器进行解压,然后进行一系列的安装即可。


以上步骤完成之后在php.ini中增加如下配置:

[xhprof]
extension=/usr/lib64/php/modules/xhprof.so  #xhprof.so文件路径换成你自己的
xhprof.output_dir=/tmp/xhprof


接着在/tmp目录创建一个xhprof文件夹,并赋予777权限,用来保存xhprof分析所得出的日志文件

mkdir /tmp/xhprof/

chmod -R 777 /tmp/xhprof/ #这里就直接省事给777了。。


注意:

①、./configure 不一定需要增加--with-php-config,只有当服务器有多个版本php的时候,或者php-config没有在/usr/bin的时候才需要指定php-config文件的路径位置


②、xhprof的output_dir配置项需要可读可写的权限,我们在上面已经配置过了。xhprof.output_dir是xhprof的输出目录,每次执行 xhprof的save_run方法时都会生成一个 run_id.project_name.xhprof 文件。这个目录在哪里并不重要(按照本文的配置,目前该目录的位置在/tmp/xhprof/)。注意此路径的权限要可读写!否则文件无法生成成功。

xhprof是否安装成功的验证

如果你的phpinfo中有显示xhprof扩展信息,则说明安装成功。

安装成功示例截图如下:

p0.png

简单使用

xhprof工具需要引入2个类库:

还记得之前下载的源码吧?把里面的xhprof_lib目录复制一份儿,复制到你的项目目录中,并且在你需要分析的php代码中进行引入(你需要在哪里进行分析php代码性能,就在哪里的php代码中引入下面这2个文件):

include_once '/home/wwwroot/default/xhprof/xhprof_lib/utils/xhprof_lib.php';
include_once '/home/wwwroot/default/xhprof/xhprof_lib/utils/xhprof_runs.php';

开启性能分析:使用 xhprof_enable() 函数

xhprof_enable(XHPROF_FLAGS_CPU|XHPROF_FLAGS_MEMORY|XHPROF_FLAGS_NO_BUILTINS);

//XHPROF_FLAGS_NO_BUILTINS (integer)
//使得跳过所有内置(内部)函数

//XHPROF_FLAGS_CPU (integer)
//使输出的性能数据中添加 CPU 数据

//XHPROF_FLAGS_MEMORY (integer)
//使输出的性能数据中添加内存数据


//当然了,这些预定义常量是可选的,不写也可以,直接在相关php代码块中调用 xhprof_enable(); 即可

关闭性能分析:使用 xhprof_disable() 函数,并将分析的结果保存起来

$data = xhprof_disable(); //关闭性能分析

$obj_xhprof_run = new XHProfRuns_Default();
$run_id         = $obj_xhprof_run->save_run($data, "test"); //把性能分析的报告保存到output_dir目录

var_dump($run_id); //$run_id是本次报告的一个报告id,用来标识本次报告的唯一性,相当于数据表中的主键id,下面查看性能的时候会用到这个$run_id

xhprof工具的完整使用示例代码如下:

<?php

include_once '/home/wwwroot/default/xhprof/xhprof_lib/utils/xhprof_lib.php';
include_once '/home/wwwroot/default/xhprof/xhprof_lib/utils/xhprof_runs.php';

xhprof_enable();  //开启性能分析检测

include_once './mysql.php';

$sql     = "SELECT * FROM employee";
$sql_one = "SELECT * FROM employee WHERE id = 3";

$result = Mysql::getAll($sql);
$row    = Mysql::getRow($sql_one);

//echo "<pre>";

//print_r($result);

//echo "<hr/>";

//print_r($row);

$data = xhprof_disable(); //关闭性能分析

$obj_xhprof_run = new XHProfRuns_Default();
$run_id         = $obj_xhprof_run->save_run($data, "test"); //保存性能分析报告

var_dump($run_id); //输出本次性能分析的报告id

然后访问一下该文件,就会记录该文件的php代码的性能分析报告。

查看性能分析:

还记得之前下载的源码吧?把里面的 xhprof_html 目录复制出来,单独做成一个目录,并通过nginx或apache配置成一个可访问的站点目录:

示例截图如下:

p3.png


并且把之前的 xhprof_lib 复制一份到同级目录(也就是说 xhprof_lib 和 xhprof_html 这两个文件夹是在同一个目录下,也就是同级的关系),目录示例截图如下:

p4.png


接下来,我们访问这个站点:

p5.png

上图中可以看到,会显示出所有的你已经分析完毕,并保存的分析报告文件,其中xxxxxxx.test.xhprof就是我们上面所说的$run_id(也就是 报告id)。


点击其中一个进行查看:

p3.png

如上图所示,这样就可以查看到所有代码执行的cpu消耗,执行时间,占用情况了,根据这份数据,去优化最耗时间的代码就可以了。其中Calls、Incl. Wall Time(microsec)、Excl. Wall Time(microsec)这三个单词,点击 可以将下面显示的结果进行降序排序。


根据上图显示的结果,这里列举一些常用的名词的解释:

Function Name:方法名称。


Calls:方法被调用的次数。


Calls%:方法调用次数在同级方法总数调用次数中所占的百分比。


Incl.Wall Time(microsec):方法执行花费的时间,包括子方法的执行时间。(单位:微秒)


IWall%:方法执行花费的时间百分比。


Excl. Wall Time(microsec):方法本身执行花费的时间,不包括子方法的执行时间。(单位:微秒)


EWall%:方法本身执行花费的时间百分比。


Incl. CPU(microsecs):方法执行花费的CPU时间,包括子方法的执行时间。(单位:微秒)


ICpu%:方法执行花费的CPU时间百分比。


Excl. CPU(microsec):方法本身执行花费的CPU时间,不包括子方法的执行时间。(单位:微秒)


ECPU%:方法本身执行花费的CPU时间百分比。


Incl.MemUse(bytes):方法执行占用的内存,包括子方法执行占用的内存。(单位:字节)


IMemUse%:方法执行占用的内存百分比。


Excl.MemUse(bytes):方法本身执行占用的内存,不包括子方法执行占用的内存。(单位:字节)


EMemUse%:方法本身执行占用的内存百分比。


Incl.PeakMemUse(bytes):Incl.MemUse峰值。(单位:字节)


IPeakMemUse%:Incl.MemUse峰值百分比。


Excl.PeakMemUse(bytes):Excl.MemUse峰值。单位:(字节)


EPeakMemUse%:Excl.MemUse峰值百分比。


也可以查看请求执行的流程图:

上面那个图中,有一个 [View Full Callgraph] 点击这里,可以查看该分析报告的请求执行流程图,如果点击之后报如下错误:

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

p1.png

说明服务器没有安装画图软件 graphviz,centos系统直接使用:yum -y install graphviz  一键安装即可。


点击 [View Full Callgraph] 之后的示例截图如下:

p2.png

如上图所示,xhprof会通过 黄色,红色,以及一根比较粗的灰色的线,为我们标识出主要的耗时路线。调用红色是耗时最大的函数调用,通过分析这个图片我们可以看出哪里耗时长,从而有针对性的去做优化。


本文所使用的相关文件:相关文件.zip

如果你要使用本文的相关文件,请下载解压之后,自行调整适合你自己的对应的文件路径。


本文介绍的只是xhprof工具在linux上如何使用,xhprof在windows上如何使用可参考以下链接:

https://www.cnblogs.com/qq917937712/p/8889001.html

https://www.cnblogs.com/buexplain/p/4821619.html



今天进步一点点,明天梦想近点点!



声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

小周博客
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

精彩评论

全部回复 0人评论 7,777人参与

loading