利用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调用MySQL的存储过程的实现代码
Aug 12 PHP
《PHP编程最快明白》第三讲:php数组
Nov 01 PHP
探讨fckeditor在Php中的配置详解
Jun 08 PHP
6种php上传图片重命名的方法实例
Nov 04 PHP
php 判断网页是否是utf8编码的方法
Jun 06 PHP
Parse正式发布开源PHP SDK
Aug 11 PHP
PHP技术开发微信公众平台
Jul 22 PHP
php示例详解Constructor Prototype Pattern 原型模式
Oct 15 PHP
PHP 中 Orientation 属性判断上传图片是否需要旋转
Oct 16 PHP
CI(CodeIgniter)模型用法实例分析
Jan 20 PHP
Yii2.0框架behaviors方法使用实例分析
Sep 30 PHP
Centos7安装swoole扩展操作示例
Mar 26 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 include_path设置技巧分享
2011/07/03 PHP
谈谈关于php的优点与缺点
2013/04/11 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
jQuery 选择器理解
2010/03/16 Javascript
jquery的$(document).ready()和onload的加载顺序
2010/05/26 Javascript
js判断鼠标同时离开两个div的思路及代码
2013/05/31 Javascript
深入分析JSONP跨域的原理
2014/12/10 Javascript
HTML5实现留言和回复页面样式
2015/07/22 Javascript
尝试动手制作javascript放大镜效果
2015/12/25 Javascript
jQuery Ajax页面局部加载方法汇总
2016/06/02 Javascript
全面解析Javascript无限添加QQ好友原理
2016/06/15 Javascript
JavaScript页面实时显示当前时间实例代码
2016/10/23 Javascript
javascript  数组排序与对象排序的实例
2017/07/17 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
2017/10/30 Javascript
Vue-router 中hash模式和history模式的区别
2018/07/24 Javascript
JS实现基本的网页计算器功能示例
2020/01/16 Javascript
Vue项目利用axios请求接口下载excel
2020/11/17 Vue.js
[02:05]2014DOTA2西雅图邀请赛 老队长全明星大猜想谁不服就按进显示器
2014/07/08 DOTA
[01:22:19]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第二场 6.2
2018/06/03 DOTA
python socket 超时设置 errno 10054
2014/07/01 Python
Python实现短网址ShortUrl的Hash运算实例讲解
2015/08/10 Python
python数据类型判断type与isinstance的区别实例解析
2017/10/31 Python
解决使用PyCharm时无法启动控制台的问题
2019/01/19 Python
解决Django 在ForeignKey中出现 non-nullable field错误的问题
2019/08/06 Python
python用WxPython库实现无边框窗体和透明窗体实现方法详解
2020/02/21 Python
tensorflow模型文件(ckpt)转pb文件的方法(不知道输出节点名)
2020/04/22 Python
Mavi牛仔裤美国官网:土耳其著名牛仔品牌
2016/09/24 全球购物
美国购买新书和二手书网站:Better World Books
2018/10/31 全球购物
户外婚礼策划方案
2014/02/08 职场文书
2015年护士节慰问信
2015/03/23 职场文书
社区党建工作总结2015
2015/05/13 职场文书
收入证明怎么写
2015/06/12 职场文书
学校教师培训工作总结
2015/10/14 职场文书
2016年党建工作简报
2015/11/26 职场文书
Python pyecharts绘制条形图详解
2022/04/02 Python
python实现一个简单的贪吃蛇游戏附代码
2022/06/28 Python