php性能分析工具-xhprof接入
后台-插件-广告管理-内容页头部广告(手机) |
xhprof介绍
XHProf是一个分层PHP性能分析工具。它报告函数级别的请求次数和各种指标,包括阻塞时间,CPU时间和内存使用情况。一个函数的开销,可细分成调用者和被调用者的开销,XHProf数据收集阶段,它记录调用次数的追踪和包容性的指标弧在动态callgraph的一个程序。它独有的数据计算的报告/后处理阶段。在数据收集时,XHProfd通过检测循环来处理递归的函数调用,并通过给递归调用中每个深度的调用一个有用的命名来避开死循环。XHProf分析报告有助于理解被执行的代码的结构,它有一个简单的HTML的用户界面( PHP写成的)。基于浏览器的性能分析用户界面能更容易查看,或是与同行们分享成果。也能绘制调用关系图。
安装接入xhprof
1.下载安装xhprof
- 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
- 新建xhprof 的输出目录
- 1
- 2
- 将xhprof相关文件复制到项目目录中
- 1
- 2
- 3
- 4
用参数调用 /login?xhprof
login
脚本接入
- 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
- 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
后台-插件-广告管理-内容页尾部广告(手机) |