利用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 相关文章推荐
用PHP4访问Oracle815
Oct 09 PHP
PHP has encountered an Access Violation 错误的解决方法
Jan 17 PHP
五款常用mysql slow log分析工具的比较分析
May 22 PHP
PHP原生模板引擎 最简单的模板引擎
Apr 25 PHP
PHP利用func_get_args和func_num_args函数实现函数重载实例
Nov 12 PHP
PHP中SSO Cookie登录分析和实现
Nov 06 PHP
使用PHP uniqid函数生成唯一ID
Nov 18 PHP
php微信公众号开发之现金红包
Apr 16 PHP
PHP基于SPL实现的迭代器模式示例
Apr 22 PHP
PHP设计模式之适配器模式原理与用法分析
Apr 25 PHP
php正确输出json数据的实例讲解
Aug 21 PHP
PHP7修改的函数
Mar 09 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获取后台Job管理的实现代码
2011/06/10 PHP
Yii2中关联查询简单用法示例
2016/08/10 PHP
javascript 出生日期和身份证判断大全
2008/11/13 Javascript
JS高级笔记
2011/07/13 Javascript
jquery如何获取复选框的值
2013/12/12 Javascript
JavaScript实现将UPC转换成ISBN的方法
2015/05/26 Javascript
jquery+ajax实现注册实时验证实例详解
2015/12/08 Javascript
jQuery插件Easyui设置datagrid的pageNumber导致两次请求问题的解决方法
2016/08/06 Javascript
Bootstrap企业网站实战项目4
2016/10/14 Javascript
Webpack框架核心概念(知识点整理)
2017/12/22 Javascript
浅谈super-vuex使用体验
2018/06/25 Javascript
JS实现点击拉拽轮播图pc端移动端适配
2018/09/05 Javascript
webstorm中配置Eslint的两种方式及差异比较详解
2018/10/19 Javascript
Vue开发之watch监听数组、对象、变量操作分析
2019/04/25 Javascript
搭建Vue从Vue-cli到router路由护卫的实现
2019/11/14 Javascript
JavaScript动画实例之粒子文本的实现方法详解
2020/07/28 Javascript
使用python编写脚本获取手机当前应用apk的信息
2014/07/21 Python
使用python实现knn算法
2017/12/20 Python
python使用tkinter实现简单计算器
2018/01/30 Python
Win7 64位下python3.6.5安装配置图文教程
2020/10/27 Python
python3.5绘制随机漫步图
2018/08/27 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
完美解决ARIMA模型中plot_acf画不出图的问题
2020/06/04 Python
10种CSS3实现的loading动画,挑一个走吧?
2020/11/16 HTML / CSS
ToysRus日本官网:玩具反斗城
2018/09/08 全球购物
广州御银科技股份有限公司试卷(C++)
2016/11/04 面试题
护士在校生自荐信
2014/02/01 职场文书
党员违纪检讨书
2014/02/18 职场文书
个人存款证明书
2014/10/18 职场文书
先进个人总结范文
2015/02/15 职场文书
党课主持词大全
2015/06/30 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python
JavaScript 中for/of,for/in 的详细介绍
2021/11/17 Javascript
python opencv将多个图放在一个窗口的实例详解
2022/02/28 Python
MyBatis XPathParser解析器使用范例详解
2022/07/15 Java/Android