说明

将xhprof部署在线上环境,在特定情况下进行性能分析,方便快捷的排查线上性能问题。

通过参数指定及添加代码行触发进入性能分析,并将结果保存入MongoDB。

因为xhprof对性能的影响,只部署在一台机子上。

环境配置

PHP 5.5.25
xhprof-0.9.4

xhprof:git@github.com:phacility/xhprof.git

核心入口文件

/PATH/xhprof/config/inject.php


<?php //根据条件是否进入性能分析
if( !function_exists('xphrof_checkEnable') ){
//返回值,ture-进入, false-不进入
function xphrof_checkEnable($cmdName=''){
//如果是脚本,直接进
if( !empty($cmdName) ){
return true;
} //方法一:根据参数进
$enable = !empty($_GET['showyourbug']) || !empty($_POST['showyourbug']);
//方法二:根据百分比或随机
//$enable = rand(0, 100) === 42; //方法三:使用唯一性数据(ip\host\op_user) return $enable;
}
} //获取标识请求的唯一性数据
if( !function_exists('xphrof_getUniqSign') ){ function xphrof_getUniqSign($cmdName=''){
//请求的标识-ip
$clientIp = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : php_uname('n'); //请求的标识-路由
$path = 'unknow';
if( isset($_SERVER["REQUEST_URI"]) ){
$purl = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
$path = 'http-' . (!empty($purl) ? str_replace('/','-', trim($purl, ' /')) : 'unknow');
}else{
$path = 'cmd-' . ( !empty($cmdName) ? str_replace('\\','-', trim($cmdName, ' \\')): 'unknow');
} //尝试从cookie中取用户名 //执行分析的服务器
$hostName = php_uname('n'); return [
'ip' => $clientIp,
'path' => $path,
'hostname' => $hostName
];
}
} //主处理过程
if( !function_exists('xphrof_mainProcess') ){ function xphrof_mainProcess($cmdName=''){ if ( extension_loaded('xhprof') ) { //xhprof功能统一开关,紧急情况下使用
$xhprofMainSwitch = true; //true-开, false-关 //判断是否进入分析
$enable = xphrof_checkEnable($cmdName); if ( $xhprofMainSwitch && $enable ) { $pathData = xphrof_getUniqSign($cmdName); //开始性能分析
// XHPROF_FLAGS_NO_BUILTINS - 使得跳过所有内置(内部)函数
// XHPROF_FLAGS_CPU - 使输出的性能数据中添加 CPU 数据
// XHPROF_FLAGS_MEMORY - 使输出的性能数据中添加内存数据
xhprof_enable( XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU ); //注册,脚本执行完或exit后执行
register_shutdown_function(function() use ($pathData){ //xhprof的数据
$xhprofData = xhprof_disable(); //相应给客户端并结束请求
$returnClient = -1;
if (function_exists('fastcgi_finish_request')) {
$returnClient = fastcgi_finish_request();
} //当前环境数据及post、get数据
$envData = [
'env' => $_SERVER,
'get' => $_GET,
'post' => $_POST,
'return_client' => intval($returnClient)
]; $XHPROF_ROOT = realpath(dirname(__FILE__) .'/..');
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs_mongo.php";
include_once $XHPROF_ROOT . "/xhprof_lib/service/MongoBaseSvc.php";
//加载配置文件
$xhprofConfig = include_once $XHPROF_ROOT . '/config/config.php'; $xhprofRuns = new XHProfRuns_Mongo($xhprofConfig); $xhprofRuns->save_run($xhprofData, $envData, $pathData); });
}
}
}
} //默认启动一次-http,指定服务器才可执行
if( function_exists('php_uname') && in_array(php_uname('n'), [
'10.10.10.10', //测试开发服务器
'11.11.11.11' //线上执行服务器
], true) ){
xphrof_mainProcess();
} //comand进入分析
if( !function_exists('xphrof_startProcess') ){
function xphrof_startProcess($cmdName=''){
xphrof_mainProcess($cmdName);
}
}

加载入口文件方案

1. 在项目启动的配置文件中加载


//例如:bootstrap/autoload.php
/*
|--------------------------------------------------------------------------
| add xhprof config
|--------------------------------------------------------------------------
|
| inject xhprof config.
|
*/
$xhprofFile = __DIR__.'/../xhprof/config/inject.php';
if (file_exists($xhprofFile)) {
require_once $xhprofFile;
}

2. 在项目nginx的配置中加载


//在 nginx 的fastcgi配置处
set $xhprofconf "auto_prepend_file=/PATH/xhprof/config/inject.php";
fastcgi_param PHP_VALUE $xhprofconf;

触发进入

  1. 对HTTP请求访问时增加参数:showyourbug=1
  2. 对CLI脚本代码中增加:xphrof_startProcess(__CLASS__);

MongoDB保存结构

解析保存xhprof_disable()返回的数据、请求的环境变量及数据。可设置过期索引保存指定时长日志。


{
"ip" : "10.10.10.10", //访问客户端ip
"path" : "http-", //资源标识,http-接口请求,cmd-artisan脚本执行
"hostname" : "machine_host_name", //执行机器名称
"run_id" : "5afe795c96a83", //唯一run_id
"main" : { //整体数据
"ct" : NumberLong(1),
"wt" : NumberLong(36),
"cpu" : NumberLong(0),
"mu" : NumberLong(1856),
"pmu" : NumberLong(672)
},
"xhprof_raw_data" : "a:2:{s:23:\"main()==>xhprof_disable\";a:5:{s:2:\"ct\";i:1;s:2:\"wt\";i:8;s:3:\"cpu\";i:0;s:2:\"mu\";i:840;s:3:\"pmu\";i:96;}s:6:\"main()\";a:5:{s:2:\"ct\";i:1;s:2:\"wt\";i:36;s:3:\"cpu\";i:0;s:2:\"mu\";i:1856;s:3:\"pmu\";i:672;}}", //原始数据体
"env_data" : { //相关环境日志
"env" : { //$_SERVER信息
"USER" : "nobody",
"HOME" : "/",
"FCGI_ROLE" : "RESPONDER",
"SCRIPT_FILENAME" : "/PATH/public/index.php",
......
"REQUEST_TIME" : NumberLong(1526626652)
},
"get" : { //$_GET信息
"showyourbug" : "1"
},
"post" : [], //$_POST信息
"return_client" : NumberLong(-1) //fastcgi_finish_request相应客户端结果
},
"index_time" : ISODate("2018-05-18T06:57:32.000Z"), //过期索引,保留2天
"create_time" : "2018-05-18 14:57:32" //创建时间
}

对线上性能的影响分析

测试接口


public function getHello(){
$ret = [
'errno' => 0,
'errmsg' => 'success'
];
return json_encode($ret);
}

使用ab请求


ab -n 1000 -c 100 -X 10.10.10.10:80 http://hostname/hello
ab -n 1000 -c 100 -X 10.10.10.10:80 http://hostname/hello?showyourbug=1

测试结果
批量请求对服务器影响:
| 测试类别 | Requests per second (#/sec) | 平均 | Time per request (ms) | 平均 |
| 仅测试接口 | 49.23,50.02,49.41 | 49.55 | 20.312,19.992,20.239 | 20.181 |
| 加载配置(未进入) | 46.74,45.48,45.21 | 45.81 (-8.76%) | 21.397,21.987,22.118 | 21.834 (-8.19%) |
| 加载配置(进入) | 10.72,10.48,11.46 | 10.88 (-78%) | 93.281,95.452,87.259 | 91.99 (-355.82%) |

对单个请求影响:
| 测试类别 | Time per request (ms) | 平均 |
| 仅测试接口 | 66.972,87.029,72.605 | 75.54 |
| 加载配置(未进入) | 79.183,80.728,83.101 | 81.004 (-7.23%) |
| 加载配置(进入) | 275.186,287.293,291.312 | 284.597 (-271.45%) |

结论

xhprof会影响线上性能,所以只部署到一台线上机进行监控。

原文地址:https://segmentfault.com/a/1190000015591262

xphrof性能分析线上部署实践的更多相关文章

  1. ASP.NET Core在CentOS上的最小化部署实践

    引言        本文从Linux小白的视角, 在CentOS 7.x服务器上搭建一个Nginx-Powered AspNet Core Web准生产应用. 在开始之前,我们还是重温一下部署原理,正 ...

  2. 在阿里云ECS CentOS7上部署基于MongoDB+Node.js的博客

    前言:这是一篇教你如何在阿里云的ECS CentOS 7服务器上搭建一个个人博客的教程,教程比较基础,笔者尽可能比较详细的把每一步都罗列下来,包括所需软件的下载安装和域名的绑定,笔者在此之前对Linu ...

  3. VNF网络性能提升解决方案及实践

    VNF网络性能提升解决方案及实践 2016年7月 作者:    王智民 贡献者:     创建时间:    2016-7-20 稳定程度:    初稿 修改历史 版本 日期 修订人 说明 1.0 20 ...

  4. 腾讯云-ASP.NET Core+Mysql+Jexus+CDN上云实践

    腾讯云-ASP.NET Core+Mysql+Jexus+CDN上云实践.md 开通腾讯云服务器和Mysql 知识点: ASP.NET Core和 Entity Framework Core的使用 L ...

  5. zz开源 MNN:淘宝在移动 AI 上的实践

    开源 MNN:淘宝在移动 AI 上的实践   陈以鎏(离青) 阅读数:40612019 年 6 月 28 日   随着深度学习的快速发展和端侧设备算力的不断提升,原本在云端执行的推理预测工作正在部分迁 ...

  6. 滴滴推理引擎IFX:千万规模设备下AI部署实践

    桔妹导读:「滴滴技术」将于本月开始,联合各技术团队为大家带来精彩分享.你想了解的技术干货,深度专访,团队及招聘将于每周三与你准时见面.本月为「滴滴云平台事业群分享月」,在今天的内容中,云平台事业群-机 ...

  7. 在 CentOS7 上部署 zookeeper 服务

    在 CentOS7 上部署 zookeeper 服务 1 用 SecureCRT 或 XShell 等 Linux 客户端工具连接至 CentOS7 服务器: 2 进入到 /usr/local/too ...

  8. [转]基于AWS的自动化部署实践

    作者 徐桂林 发布于 2014年1月22日 -------------------------------------------------------------------- 1. 背景 在过去 ...

  9. 虚拟机评估——如何确定一个CPU核上部署的虚拟机数量?

    最近研究虚拟化技术,不可避免遇到一个问题:如何评估物理主机上虚拟主机的容量?下面这篇文章的思路有一定的启发性,转发一下. 如何确定一个CPU核上部署的虚拟机数量? 摘要:本文说明一个CPU核上部署虚拟 ...

随机推荐

  1. poj 2391 Ombrophobic Bovines【最大流】

    我%--&(¥--,调了一下午,最后发现P赋值1e5能过,赋值1e6就会TLE致死.改了一下午加一晚上然而这是为什么??? 一种常见的建图套路,首先二分答案,注意上界要取大一点,1e9是不行的 ...

  2. 【先定一个小目标】Ubuntu 16.04 搭建 zookeeper

    ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效.高可用的分布式协调服务,提供了诸如数据发布/订阅.负载均衡.命名服务.分布式协调/通知和分布式锁等分布式基础服务.由于 Zo ...

  3. 表达式语言EL简单学习

    Jsp2.0最重要的特性就是表达式语言EL.jsp用户可以用它来访问应用程序数据. EL表达式以${开头并以}结束. ${expresion}     ${x+y} 它也常用来连接两个表达式,取值将从 ...

  4. sdut1642Simple Arithmetics(模拟)

    链接 发个长长的模拟 这题要注意的地方挺多 -的个数 以及对齐的情况 全都注意好了 大数的加减乘就可以了 #include <iostream> #include<cstdio> ...

  5. JS-表格数据的添加与删除、搜索

    <!doctype html><html><head><meta charset="utf-8"><title>JS练习 ...

  6. [转]WF事件驱动

    本文转自:http://www.cnblogs.com/Mayvar/archive/2011/09/03/wanghonghua_201109030446.html 已经有不少朋友知道Workflo ...

  7. Nexus3.0搭建私服上传JAR包 Windows10

    背景 近期换了一个项目组,用的是公司自研产品,涉及到很多内部JAR包引用,版本号很多,每次更新都是产品部给出jar包,项目组成员各自复制一套本地替换,来了新人各种安装配置,复杂度太高,这不,我一来,又 ...

  8. 希尔排序法及其js实现

    希尔(Shell)排序又称为缩小增量排序,它是一种插入排序.它是直接插入排序算法的加强版. 希尔增量: 希尔增量是指希尔提出了一种冲破二次时间屏障的算法. Donald Shell 提出了一种冲破二次 ...

  9. 微信小程序组件解读和分析:七、button按钮

    button按钮组件说明: button,顾名思义,按钮,类似于html的button标签.我们可以设置按钮的属性,比如字体颜色大小,背景颜色等,可以给按钮绑定事件,用户点击时会触发事件. butto ...

  10. InChatter系统之本地化

    InChatter现在支持本地化了,其实这个只是很细节的东西,但是咱也是可以走走国际范.哈哈 其实最重要的原因只是想进行一次本地化的开发.这个概念相信大部分人都有,但是在实际项目中真的很少会涉及到,我 ...