很多项目,还没到考虑性能的时候就夭折了,而你项目是否到了要考虑性能优化的时候了?

何时需要做性能分析

经常会有人问,我的cpu正常,内存正常,数据库正常,可网站打开为什么就是?为什么就是

在当今硬件如此廉价的时候,也许考虑代码性能并非必要,要么人遭罪,要么钱遭罪,8G不够换16G,一台不行,加两台。。。

这种拿空间换时间的做法,固然可以,但并非长久之计。

如果你想快速定位代码问题,找到代码瓶颈,那么就该学会做性能分析了。

php的性能分析工具也很多,例如:xhprof、tideways、xdebug等。

XHProf是Facebook 推出了一个被动分析器,可用于生产环境。

安装xhprof

git下载,切换到扩展目录

git clone https://github.com/longxinH/xhprof.git ./xhprof
cd xhprof/extension/

这里以php7为例,如果是php5.*,请使用https://github.com/phacility/xhprof.git

编译扩展,phpize在php的安装目录可找到

/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && sudo make install

编辑php配置文件,在配置文件最后追加:

[xhprof]
extension = xhprof.so
xhprof.output_dir = /tmp/xhprof

这里xhprof.output_dir是性能分析的文件存放目录,需要php运行用户的目录写权限

chown -R www:www /tmp/xhprof

另外,在分析绘图的时候回用到这个proc_open函数,如果没有开启需要开启。

修改完配置,记得重启php-fpm,使用

php -m |grep xhprof

查看xhprof扩展是否安装成功。

安装绘图工具graphviz

yum install libpng
yum install graphviz

运行

在刚刚git clone下来的那个xhprof包有个example的例子

将xhprof 放到一个站点目录

访问

http://您的域名/xhprof/examples/sample.php

会看到

Array
(
    [foo==>bar] => Array
        (
            [ct] => 5
            [wt] => 29
        )
、、、、

)
---------------
Assuming you have set up the http based UI for 
XHProf at some address, you can view run at 
http://<xhprof-ui-address>/index.php?run=5b6116ddebeee&source=xhprof_foo
---------------

复制其中的参数,?run=5b6116ddebeee&source=xhprof_foo,打开:

http://您的域名/xhprof/xhprof_html/index.php?run=5b6116ddebeee&source=xhprof_foo

就可以看到分析的结果了。

点击[View Full Callgraph] 就可以看到函数的调用关系和运行时长了,红色标记的地方,就是就是耗时最长的了,定位代码着重优化。

如果报错

failed to execute cmd " dot -Tpng"

确认是否开启proc_open函数,并且安装graphviz

打开 http://您的域名/xhprof/xhprof_html/index.php 可以看到所有分析结果.

在自己的项目中使用

想要在自己的项目中使用,可以参考xhprof/examples/sample.php 这个文件

首先,将xhprof/xhprof_lib 目录拷贝自己的项目里,

在程序入口文件开头加入:

xhprof_disable();

在结尾加入:

$XHPROF_ROOT = realpath(dirname(__FILE__) .'/..');
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";

// save raw data for this profiler run using default
// implementation of iXHProfRuns.
$xhprof_runs = new XHProfRuns_Default();

// save the run under a namespace "xhprof_foo"
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");

运行一下你的程序,就可通过http://您的域/xhprof/xhprof_html/index.php 查看分析结果。

分析概要说明:

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峰值百分比。