利用PHP扩展Xhprof分析项目性能实践教程


Posted in PHP onSeptember 05, 2018

一、背景

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

XHProf 是 FaceBook 开发的一个函数级别的 PHP 分层分析器。

数据收集部分是一个基于 C 的 PHP 扩展,分析报告是一系列基于 PHP 的 HTML 导航页面。

XHProf 能统计每个函数的调用次数、内存使用、CPU占用等多项重要的数据。

并且 XHProf 还能比较两个统计样本,或从多个数据样本中汇总结果。

XHProf 是分析 PHP 程序执行效率的利器,能让我们得到更底层的的分析数据。

下面话不多说了,来一起看看详细的介绍吧

二、操作步骤

  • 安装扩展
  • 配置扩展
  • 测试分析

三、安装

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

3.1 下载源码

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

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

3.2 检测环境

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

cd xhprof/extension/

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

phpize

返回结果如下

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

3.3 编译安装

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

./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

返回结果如下

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

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

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

四、配置

在编译安装源码之后,笔者还需要对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,如下图所示

利用PHP扩展Xhprof分析项目性能实践教程

五、测试

经过上面的操作笔者已经成功的安装与配置,现在需要用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 结果分析

运行后结果,如下图

利用PHP扩展Xhprof分析项目性能实践教程

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

利用PHP扩展Xhprof分析项目性能实践教程

在页面中有一个列表,展示了每一个方法所消耗的时间,如果觉得列表的方式表示不够清晰,点击页面中的 View Full Callgraph 链接可以直接生成一个图片,如下图所示

利用PHP扩展Xhprof分析项目性能实践教程

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
PHP仿盗链代码
Jun 03 PHP
PHP中Header使用的HTTP协议及常用方法小结
Nov 04 PHP
Yii的CDbCriteria查询条件用法实例
Dec 04 PHP
php实现的一个简单json rpc框架实例
Mar 30 PHP
PHP四种基本排序算法示例
Apr 09 PHP
php实现计算百度地图坐标之间距离的方法
May 05 PHP
php版微信公众平台接口参数调试实现判断用户行为的方法
Sep 23 PHP
PHP请求远程地址设置超时时间的解决方法
Oct 29 PHP
PHPstorm快捷键(分享)
Jul 17 PHP
对于Laravel 5.5核心架构的深入理解
Feb 22 PHP
PHP格式化显示时间date()函数代码
Oct 03 PHP
win10下 php安装seaslog扩展的详细步骤
Dec 04 PHP
PHP时间处理类操作示例
Sep 05 #PHP
PHP命名空间与自动加载类详解
Sep 04 #PHP
ThinkPHP框架实现定时执行任务的两种方法分析
Sep 04 #PHP
php 后端实现JWT认证方法示例
Sep 04 #PHP
PHP利用Mysql锁解决高并发的方法
Sep 04 #PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
Sep 03 #PHP
PHP实现的AES双向加密解密功能示例【128位】
Sep 03 #PHP
You might like
简体中文转换为繁体中文的PHP函数
2006/10/09 PHP
php microtime获取浮点的时间戳
2010/02/21 PHP
解析php中mysql_connect与mysql_pconncet的区别详解
2013/05/15 PHP
浅谈php serialize()与unserialize()的用法
2013/06/05 PHP
php获取从html表单传递数组的方法
2015/03/20 PHP
php中array_column函数简单实现方法
2016/07/11 PHP
thinkphp配置文件路径的实现方法
2016/08/30 PHP
php把字符串指定字符分割成数组的方法
2018/03/12 PHP
关于Blog顶部的滚动导航条代码
2006/09/25 Javascript
简单的无缝滚动程序-仅几行代码
2007/05/08 Javascript
javascript入门·对象属性方法大总结
2007/10/01 Javascript
基于jquery的关于动态创建DOM元素的问题
2010/12/24 Javascript
EXT窗口Window及对话框MessageBox
2011/01/27 Javascript
js函数setTimeout延迟执行的简单介绍
2013/07/17 Javascript
jquery的相对父元素和相对文档定位示例代码
2013/08/02 Javascript
两种方法实现在HTML页面加载完毕后运行某个js
2014/06/16 Javascript
textarea不能通过maxlength属性来限制字数的解决方法
2014/09/01 Javascript
浅谈javascript中createElement事件
2014/12/05 Javascript
node.js中的buffer.toJSON方法使用说明
2014/12/14 Javascript
详解Matlab中 sort 函数用法
2016/03/20 Javascript
实用又漂亮的BootstrapValidator表单验证插件
2016/05/30 Javascript
Three.js学习之正交投影照相机
2016/08/01 Javascript
jQuery实现动态给table赋值的方法示例
2017/07/04 jQuery
vue实现分页组件
2020/06/16 Javascript
微信小程序之 catalog 切换实现解析
2019/09/12 Javascript
使用Python装饰器在Django框架下去除冗余代码的教程
2015/04/16 Python
利用Python中的pandas库对cdn日志进行分析详解
2017/03/07 Python
Python基于生成器迭代实现的八皇后问题示例
2018/05/23 Python
python sort、sort_index方法代码实例
2019/03/28 Python
Django 实现图片上传和显示过程详解
2019/07/18 Python
HTML5事件方法全部汇总
2016/05/12 HTML / CSS
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
查询优化的一般准则有哪些
2015/03/08 面试题
电子商务毕业生求职信
2013/11/10 职场文书
机电专业大学生职业规划书范文
2014/02/25 职场文书
MySQL中一条update语句是如何执行的
2022/03/16 MySQL