您现在的位置是:首页 > 技术教程 正文

php性能分析工具-xhprof接入

admin 阅读: 2024-03-17
后台-插件-广告管理-内容页头部广告(手机)

xhprof介绍
XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。一个函数的开销,可细分成调用者和被调用者的开销,XHProf数据收集阶段,它记录调用次数的追踪和包容性的指标弧在动态callgraph的一个程序。它独有的数据计算的报告/后处理阶段。在数据收集时,XHProfd通过检测循环来处理递归的函数调用,并通过给递归调用中每个深度的调用一个有用的命名来避开死循环。XHProf分析报告有助于理解被执行的代码的结构,它有一个简单的HTML的用户界面( PHP写成的)。基于浏览器的性能分析用户界面能更容易查看,或是与同行们分享成果。也能绘制调用关系图。
在这里插入图片描述

安装接入xhprof
1.下载安装xhprof

wget https://pecl.php.net/get/xhprof-2.3.9.tgz tar -zxvf xhprof-2.3.9.tgz cd ./xhprof-2.3.9/extension phpize ./configure --with-php-config=/usr/local/php-7.4/bin/php-config make make install
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2. php.ini增加配置

[xhprof] extension=xhprof.so; xhprof.output_dir=/tmp/xhprof; #产生文件目录 ####其中 xhprof.output_dir 是 xhprof 的输出目录,每次执行 xhprof 的 save_run 方法时都会生成一个 run_id.project_name.xhprof 文件。这个目录在哪里并不重要。注意此路径的权限要可读写!!否则文件无法生成成功
  • 1
  • 2
  • 3
  • 4
  • 5

需要配置下 php.ini 的 error.log
在这里插入图片描述

  1. 新建xhprof 的输出目录
mkdir /tmp/xhprof chmod -R 777 /tmp/xhprof
  • 1
  • 2
  1. 将xhprof相关文件复制到项目目录中
### index.php增加内容,同级目录下新建一个xhprof目录,xhprof-2.3.9目录下xhprof_html,xhprof_lib移动至xhprof目录下。 cp -rp /root/xhprof-2.3.9/xhprof_html /home/wwwroot/xxx项目目录/xhprof/ cp -rp /root/xhprof-2.3.9/xhprof_lib /home/wwwroot/xxx项目目录/xhprof/ chmod -R 777 /home/wwwroot/xxx项目目录/xhprof/
  • 1
  • 2
  • 3
  • 4

用参数调用 /login?xhprof
login
脚本接入

<?php xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY); register_shutdown_function(function(){ $data = xhprof_disable(); //返回运行数据 //xhprof_lib 在下载的包里存在这个目录,记得将目录包含到运行的php代码中 include_once 'xhprof/xhprof_lib/utils/xhprof_lib.php'; include_once 'xhprof/xhprof_lib/utils/xhprof_runs.php'; $objXhprofRun = new XHProfRuns_Default(); $objXhprofRun->save_run($data, "xhprof"); //test 表示文件后缀 });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

xhprof使用

本地环境:http://127.0.0.1:8801/xhprof/xhprof_html/

4. 性能指标的具体含义、主要注意哪些参数

```go A、表格分析时,需要注意的指标 funciton name : 函数名 calls: 调用次数 Incl. Wall Time (microsec): 函数运行时间(包括子函数) 单位微秒 IWall%:函数运行时间(包括子函数)占比 Excl. Wall Time(microsec):函数运行时间(不包括子函数) 单位微秒 EWall%:函数运行时间(不包括子函数) B、图形分析时,需要注意的地方 红框是消耗资源占用比例最高的地方,需要着重看,根据具体数值,选择性进行优化。 黄色是消耗资源占用比例稍高的地方,根据具体数值,选择性优化。 白色是消耗资源占用比例一般的地方,基本不需要处理,不过也要根据具体数值分析。 Function Name:方法名称。 Calls:方法被调用的次数。 Calls%:方法调用次数在同级方法总数调用次数中所占的百分比。 Incl.Wall Time(microsec):方法执行花费的时间,包括子方法的执行时间。(单位:微秒) IWall%:方法执行花费的时间百分比。 Excl. Wall Time(microsec):方法本身执行花费的时间,不包括子方法的执行时间。(单位:微秒) EWall%:方法本身执行花费的时间百分比。 Incl. CPU(microsecs):方法执行花费的CPU时间,包括子方法的执行时间。(单位:微秒) ICpu%:方法执行花费的CPU时间百分比。 Excl. CPU(microsec):方法本身执行花费的CPU时间,不包括子方法的执行时间。(单位:微秒) ECPU%:方法本身执行花费的CPU时间百分比。 Incl.MemUse(bytes):方法执行占用的内存,包括子方法执行占用的内存。(单位:字节) IMemUse%:方法执行占用的内存百分比。 Excl.MemUse(bytes):方法本身执行占用的内存,不包括子方法执行占用的内存。(单位:字节) EMemUse%:方法本身执行占用的内存百分比。 Incl.PeakMemUse(bytes):Incl.MemUse峰值。(单位:字节) IPeakMemUse%:Incl.MemUse峰值百分比。 Excl.PeakMemUse(bytes):Excl.MemUse峰值。单位:(字节) EPeakMemUse%:Excl.MemUse峰值百分比。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

配置xhprof 访问域名: nginx配置:

server { listen 443; server_name wcxhprof-work.woczx.com; index index.html index.htm index.php; root /home/wwwroot/work/woc3-api/common/xhprof/xhprof_html; #ssl on; ssl_certificate /usr/local/nginx/conf/vhosts/crt/woczx.com.pem; ssl_certificate_key /usr/local/nginx/conf/vhosts/crt/woczx.com.key; ssl_session_timeout 5m; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ .php { #fastcgi #fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_pass 127.0.0.1:9001; fastcgi_index index.php; include fastcgi.conf; #pathinfo set $path_info ""; set $real_script_name $fastcgi_script_name; if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") { set $real_script_name $1; set $path_info $2; } #fastcgi conf fastcgi_param SCRIPT_FILENAME $document_root$real_script_name; fastcgi_param SCRIPT_NAME $real_script_name; fastcgi_param PATH_INFO $path_info; } location ^~ /.git { deny all; } error_log /home/logs/nginx//xhprof-woc3-error.log; location =/robots.txt { default_type text/html; add_header Contest-Type "text/plain; charset=UTF-8"; return 200 "User-Agent: *\nDisallow: /"; } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

表格分析:
在这里插入图片描述

图形分析:

在这里插入图片描述

安装和使用中遇到的问题解决办法

1.访问xhprof点击[View Full Callgraph]查看报错failed to execute cmd: " dot -Tpng"
原因一:未安装graphviz
如果看到 sh: dot: command not found ,说明服务器上没有安装画图软件graphviz
yum安装: yum install graphviz
原因二:php.ini设置了禁用proc_open方法
如果安装好了graphviz,仍然出现”failed to execute cmd”,检查下服务器上的php.ini中disable_functions这项是不是限制了proc_open,因为在xhprof_lib/utils/callgraph_utils.php的xhprof_generate_image_by_dot中使用了proc_open函数,

YII框架接入:

1.common/main.php 引入 xhprof 组件

在这里插入图片描述

namespace common\bootstraps; use Yii; use yii\base\BootstrapInterface; use yii\base\Event; use yii\web\Response; /** * xhprof分析 */ class Xhprof implements BootstrapInterface { public function bootstrap($app) { if (PHP_SAPI === 'cli') { $this->adapterCli($app); } else { $this->adapterFpm($app); } } /** * 适配CLI */ public function adapterCli($app): void { //CLI 唯一标识 $uniqueName = './yii '; if (isset($app->request->params[0])) { $uniqueName .= $app->request->params[0]; } //相同的脚本一分钟只记录一次 $key = 'xhprof_cli:' . md5($uniqueName); if ($app->cache->get($key)) { return; } //守护进程不记录 if (isDaemon()) { return; } register_shutdown_function(function () use ($app) { $data = xhprof_disable(); include_once Yii::getAlias('@common') . '/xhprof/xhprof_lib/utils/xhprof_lib.php'; include_once Yii::getAlias('@common') . '/xhprof/xhprof_lib/utils/xhprof_runs.php'; $objXhprofRun = new \XHProfRuns_Default(); $app->zipKin->setTag('xhprof.id', $objXhprofRun->save_run($data, 'cli')); }); $app->cache->set($key, 1, 60); } /** * 适配FPM */ public function adapterFpm($app): void { //加上特定标识的接口走xhprof分析 if (!isset($_GET['__xhprof'])) { return; } Event::on(Response::class, Response::EVENT_AFTER_SEND, static function () use ($app) { $data = xhprof_disable(); include_once Yii::getAlias('@common') . '/xhprof/xhprof_lib/utils/xhprof_lib.php'; include_once Yii::getAlias('@common') . '/xhprof/xhprof_lib/utils/xhprof_runs.php'; $objXhprofRun = new \XHProfRuns_Default(); $app->zipKin->setTag('xhprof.id', $objXhprofRun->save_run($data, 'fpm')); }); } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

2. 修改yii 文件 【console 的入口文件】

#!/usr/bin/env php /** * Yii console bootstrap file. */ defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); if (!isset($_SERVER['IS_DAEMON'])) { xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY); } require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/vendor/yiisoft/yii2/Yii.php'; require __DIR__ . '/common/config/bootstrap.php'; require __DIR__ . '/console/config/bootstrap.php'; $config = yii\helpers\ArrayHelper::merge( require __DIR__ . '/common/config/main.php', require __DIR__ . '/common/config/main-local.php', require __DIR__ . '/console/config/main.php', require __DIR__ . '/console/config/main-local.php' ); $application = new yii\console\Application($config); $exitCode = $application->run(); exit($exitCode);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

忽略守护进程 supervisord

supervisord 加了个环境变量 IS_DAEMON
在这里插入图片描述

/** * 是否守护进程 */ function isDaemon(): bool { return isset($_SERVER['IS_DAEMON']); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3. 修改各模块的 index.php

defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); //加上特定标识的接口走xhprof分析 if (isset($_GET['__xhprof'])) { xhprof_enable(XHPROF_FLAGS_NO_BUILTINS + XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY); } require __DIR__ . '/../../vendor/autoload.php'; require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php'; require __DIR__ . '/../../common/config/bootstrap.php'; require __DIR__ . '/../config/bootstrap.php'; $config = yii\helpers\ArrayHelper::merge( require __DIR__ . '/../../common/config/main.php', require __DIR__ . '/../../common/config/main-local.php', require __DIR__ . '/../config/main.php', require __DIR__ . '/../config/main-local.php' ); (new yii\web\Application($config))->run();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4.定期清理xhprof生成的文件

1 0 * * * find /tmp/xhprof/ -mtime +5 -name "*.xhprof" -delete;
  • 1

在这里插入图片描述

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索