一, 背景
项目即将上线, 想通过一些工具来分析代码的稳定性和效率, 想起在上个团队时使用过的 xhprof 扩展; 因为换了新电脑, 所以需要重新编译此扩展, 现将安装与实际排查过程完整记录下来, 方便自己回顾和帮助更多的读者.
二, 操作步骤
安装扩展
配置扩展
测试分析
三, 安装
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 的分析效果
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 结果分析
运行后结果, 如下图
在页面中可以看到一个 URL 地址, 复制并打开此 URL 地址之后, 便能看到此代码的分析结果, 如下图所示
在页面中有一个列表, 展示了每一个方法所消耗的时间, 如果觉得列表的方式表示不够清晰, 点击页面中的 View Full Callgraph 链接可以直接生成一个图片, 如下图所示
在图中很清晰的可以看到执行时间都消耗在 test 方法上, 因此笔者可以针对这个方法进行针对性的优化.
来源: https://segmentfault.com/a/1190000016169496