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

2. php.ini增加配置

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

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

  1. 新建xhprof 的输出目录
mkdir /tmp/xhprof
chmod -R 777 /tmp/xhprof
  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/

用参数调用 /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 表示文件后缀
});

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峰值百分比。

配置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.访问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'));
        });
    }
}

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);

忽略守护进程 supervisord

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

/**
 * 是否守护进程
 */
function isDaemon(): bool
{
    return isset($_SERVER['IS_DAEMON']);
}

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();

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

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

在这里插入图片描述

点赞(21) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部