使用PHP扩展Xhprof分析项目性能实践

1、背景

项目即将上线,想经过一些工具来分析代码的稳定性和效率,想起在上个团队时使用过的xhprof扩展;由于换了新电脑,因此须要从新编译此扩展,现将安装与实际排查过程完整记录下来,方便本身回顾和帮助更多的读者。php

2、操做步骤

  1. 安装扩展
  2. 配置扩展
  3. 测试分析

3、安装

xhprof扩展PHP并不自带,须要笔者去单独安装它,安装以后才能使用,笔者这里采用源码安装方式,安装过程以下html

3.1 下载源码

xhprof在PHP的PECL官方上面已经比较老了,笔者的PHP版本为PHP7.1所以,须要在GitHub上下载xhprof上比较新的源码,参考命令以下nginx

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

3.2 检测环境

进入编译的文件夹,参考命令git

cd xhprof/extension/

如今笔者须要编译一下源码,在编译以前可使用phpze来探测PHP的环境,参考命令以下:github

phpize

返回结果以下sql

Configuring for:
PHP Api Version:         20160303
Zend Module Api No:      20160303
Zend Extension Api No:   320160303

3.3 编译安装

生成 Makefile,为下一步的编译作准备vim

./configure

返回结果以下浏览器

creating libtool
appending configuration tag "CXX" to libtool
configure: creating ./config.status
config.status: creating config.h
config.status: config.h is unchanged

开始编译,并进行安装微信

make && make install

返回结果以下app

Build complete.
Don't forget to run 'make test'.

Installing shared extensions:     /usr/local/Cellar/php@7.1/7.1.19/pecl/20160303/

从返回信息中能够看到已经安装完成,并显示了扩展文件存放的位置

4、配置

在编译安装源码以后,笔者还须要对PHP的配置文件夹以及xhprof的进行一些简单的配置,操做过程以下所示

4.1 找出配置文件位置

要修改PHP的配置首先须要知道配置文件在什么位置,这里能够经过PHP的命令来查看配置文件存放位置,参考命令以下:

php --ini

执行命令后,返回结果以下

Configuration File (php.ini) Path: /usr/local/etc/php/7.1
Loaded Configuration File:         /usr/local/etc/php/7.1/php.ini
Scan for additional .ini files in: /usr/local/etc/php/7.1/conf.d
Additional .ini files parsed:      /usr/local/etc/php/7.1/conf.d/ext-opcache.ini

在返回结果当中,能够看到多个配置文件的路径,笔者所须要的是第二个文件php.ini

查看扩展目录存放位置,参考命令以下

cat /usr/local/etc/php/7.1/php.ini | grep extension_dir

返回结果以下

extension_dir = "/usr/local/lib/php/pecl/20160303"
; extension_dir = "ext"
; Be sure to appropriately set the extension_dir directive.
;sqlite3.extension_dir =

4.2 修改配置

从返回的结果当中,能够看到扩展的存放目录位置以下

/usr/local/lib/php/pecl/20160303

如今须要将刚才编译好的xhprof扩展复制到该目录当中,参考命令以下

cp /usr/local/Cellar/php@7.1/7.1.19/pecl/20160303/xhprof.so  /usr/local/Cellar/php@7.1/7.1.19/pecl/20160303/

经过vim编辑器编辑配置文件,参考命令以下

vim  /usr/local/etc/php/7.1/php.ini

在配置文件尾部增长xhprof的配置,以及自定义一个用来保存xhprof生成的源文件参考配置以下

[xhprof]
extension=xhprof.so
xhprof.output_dir=/data/www/xhprof/save_output_dir

4.3 重启生效

保存好以后,笔者重启php-fpm让其配置生效,重启命令能够经过brew命令来查看,参考命令以下:

brew info php@7.1

在命令执行后,返回的信息中能够看到以下信息

To have launchd start php@7.1 now and restart at login:
  brew services start php@7.1
Or, if you don't want/need a background service you can just run:
  php-fpm

所以笔者构造的重启PHP-FPM命令以下:

brew services restart php@7.1

重启完成后,返回结果以下

Stopping `php@7.1`... (might take a while)
==> Successfully stopped `php@7.1` (label: homebrew.mxcl.php@7.1)
==> Successfully started `php@7.1` (label: homebrew.mxcl.php@7.1)

4.4 验证安装

如今验证xhprof扩展是否已经安装完成,参考命令以下

php -m | grep xhprof

命令执行后,安装扩展成功的返回结果将会显示xhprof,以下图所示

image

5、测试

通过上面的操做笔者已经成功的安装与配置,如今须要用PHP代码来进行验证xhprof的分析效果

5.1 建立虚拟主机

首先建立一个虚拟主机,让用户能够经过浏览器访问所访问,建立虚拟主机须要有一个根目录,并编辑nginx配置文件,具体操做以下:

5.1.1 建立项目目录

建立项目根目录,参考命令以下

mkdir -p /Users/song/mycode/work/test

建立成功以后,笔者须要将以前git拉下来的部分代码复制到项目根目录当中,参考命令以下

cp -r xhprof/xhprof_html /Users/song/mycode/work/test/
cp -r xhprof/xhprof_lib /Users/song/mycode/work/test/

5.1.2 编辑配置文件

添加配置文件,参考命令

/usr/local/etc/nginx/nginx.conf

添加配置文件以下

server {
        listen       80;
        server_name  test.localhost;

        root   /Users/song/mycode/work/test;
        index  index.html index.htm index.php;
        
        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }


        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

    }

/etc/hosts文件中增长入一行解析记录,记录内容以下:

127.0.0.1 test.localhost

5.2 新建测试代码

在git仓库的examples文件夹下,已经有了一份demo代码,不过这份代码的注释都是英文,并且排版方式也不易笔者本身理解,所以笔者从新编辑了此文件,参考步骤以下命令

使用vim新建一个PHP文件

vim /Users/song/mycode/work/test/test.php

在文件中加入如下代码

<?php

//加载所需文件
include_once "./xhprof_lib/utils/xhprof_lib.php";
include_once "./xhprof_lib/utils/xhprof_runs.php";

//随意定义一个函数
function test($max)
{
    for ($idx = 0; $idx < $max; $idx++) {
        echo '';
    }
}

//定义测试方法
function a()
{
    test(rand(1000,5000));
}

//开始分析
xhprof_enable();

//须要分析的函数
a();

//结束分析
$xhprof_data = xhprof_disable();
//实例化xhprof类
$xhprof_runs = new XHProfRuns_Default();
//获取当前当前页面分析结果
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_foo");

echo "\nhttp://test.localhost/xhprof/xhprof_html/index.php?run=$run_id&source=xhprof_foo\n";

保存代码以后,经过浏览器访问对应的URL地址,URL地址以下所示

http://test.localhost/xhprof/test.php

5.3 结果分析

运行后结果,以下图

image

在页面中能够看到一个URL地址,复制并打开此URL地址以后,便能看到此代码的分析结果,以下图所示

image

在页面中有一个列表,展现了每个方法所消耗的时间,若是以为列表的方式表示不够清晰,点击页面中的 View Full Callgraph 连接能够直接生成一个图片,以下图所示

image

在图中很清晰的能够看到执行时间都消耗在test方法上,所以笔者能够针对这个方法进行针对性的优化。


做者:汤青松

微信:songboy8888

日期:2018-08-27