PHP性能监控
日志未经声明,均为AlloVince原创。版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可。
之前一直使用基于Xdebug进行PHP的性能分析,对于本地开发环境来说是够用了,但如果是线上环境的话,xdebug消耗较大,配置也不够灵活,因此线上环境建议使用xhprof进行PHP性能追踪及分析。
xhprof的安装与简易用法
xhprof是Facebook开源的轻量级PHP性能分析工具,Linux环境下可以通过pecl直接安装,比如在Ubuntu下仅需3行指令
pecl install xhprof-beta
echo "extension=xhprof.so" > /etc/php5/fpm/conf.d/xhprof.ini
service php5-fpm restart
之后可以通过phpinfo()
检查扩展是否已经加载。
具体如何使用呢,xhprof项目中已经提供了示例以及简易的UI,下载xhprof项目到web服务器,假设可以通过http://localhost/xhprof/
访问,那么访问http://localhost/xhprof/examples/sample.php
可以看到一些输出,并且提示通过访问http://<xhprof-ui-address>/index.php?run=XXX&source=xhprof_foo
查看结果。接下来访问http://localhost/xhprof/xhprof_html/
就可以看到已经保存的结果,列出了所有函数的调用以及所消耗的时间。
分析一下示例代码sample.php
,关键部分只有2行:
//开启xhprof并开始记录
xhprof_enable();
//运行一些函数
foo();
//停止记录并取到结果
$xhprof_data = xhprof_disable();
$xhprof_data
中记录了程序单步运行过程中所有的函数调用时间及CPU内存消耗等,具体记录哪些指标可以通过xhprof_enable
的入口参数控制,之后的处理已经与xhprof扩展无关,大致是编写了一个存储类XHProfRuns_Default
,将$xhprof_data
序列化并保存到某个目录,可以通过XHProfRuns_Default(__DIR__)
将结果输出到当前目录,如果不指定则会读取php.ini配置文件中的xhprof.output_dir
,仍然没有指定则会输出到/tmp
。
xhprof_html/index.php
将记录的结果整理并可视化,默认的UI里列出了:
- funciton name : 函数名
- calls: 调用次数
- Incl. Wall Time (microsec): 函数运行时间(包括子函数)
- IWall%:函数运行时间(包括子函数)占比
- Excl. Wall Time(microsec):函数运行时间(不包括子函数)
- EWall%:函数运行时间(不包括子函数)
每一项应该不难理解,以项目自带的sample.php
为例,示例中编写了一个main()
函数,main()
函数中调用foo()
、bar()
等一些子函数进行了一点字符处理。整个程序运行过程中,main()
函数只运行了一次,并且由于main()
函数中包括了所有的逻辑,所以main()
函数的IWall%占比为100%,但是由于main()
函数的功能都是由子函数实现的,因此main()
函数的EWall%只有0.3%,而foo()
函数完成了主要的工作,EWall%有98.1%。因此在分析更大型的程序时,往往需要根据这几项指标分别排序,从不同的角度审视性能消耗。
在xhprof_html/index.php
中还可以看到[View Full Callgraph]
链接,点击后可以绘制出一张可视化的性能分析图,如果点击后报错的话,可能是缺少依赖graphviz
,ubuntu可以通过apt安装
apt-get install graphviz
更好的注入方式
了解了上面这些,其实就已经可以将xhprof整合到任何我们已有的项目中去了。目前大部分MVC框架都有唯一的入口文件,只需要在入口文件的开始处注入xhprof的逻辑
//开启xhprof
xhprof_enable(XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_CPU);
//在程序结束后收集数据
register_shutdown_function(function() {
$xhprof_data = xhprof_disable();
//让数据收集程序在后台运行
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
}
//保存xhprof数据
...
});
但是这样免不了要修改项目的源代码,其实php本身就提供了更好的注入方式,比如将上述逻辑保存为/opt/inject.php
,然后修改php fpm配置文件
vi /etc/php5/fpm/php.ini
修改auto_prepend_file
配置
auto_prepend_file = /opt/inject.php
这样所有的php-fpm请求的php文件前都会自动注入/opt/inject.php
文件
如果使用Nginx的话,还可以通过Nginx的配置文件设置,这样侵入性更小,并且可以实现基于站点的注入。
fastcgi_param PHP_VALUE "auto_prepend_file=/opt/inject.php";
更好的分析工具:xhprof.io还是xhpgui
注入代码后我们还需要实现保存xhprof数据以及展示数据的UI,听起来似乎又是一大堆工作,有现成的轮子可以用吗?
经过搜索和比较,貌似比较好的选择有xhprof.io以及xhpgui。
两个项目做得事情差不多,都提供了xhprof数据保存功能以及一套索引展示数据的UI,下面是一些比较
xhprof.io
- ✗ 年久失修
- ✗ 保存xhprof数据到MySQL
- ✓ 支持域名、URI等多个维度的数据索引
- ✓ 函数调用记录完整,内核级别函数都能显示
- ✗ 无法针对个别URI开启
- ✗ 注入被分割成两个文件,如果程序被强制中断时xhprof数据将无法收集
xhgui
- ✓ 保存xhprof数据到MongoDB
- ✗ 不支持域名索引
- ✗ 函数调用记录不完整,部分内核级别函数(如扩展内)无法显示
- ✓ 有配置文件可以控制开启条件
- ✓ 注入只有一个文件
- ✓ 狂拽酷炫的基于D3.js的调用关系动态图
可以看到其实两个项目都不够完善,相对而言xhgui不支持域名索引对于线上调试来说是无法忍受的,因此我最后的选择是使用xhprof.io,但是自己进行了微量的调整,修改后的xhprof.io修正版支持:
- ✓ 增加开启开关配置,可以针对个别URI开启
- ✓ 注入文件合并为一个
xhprof.io修正版安装与使用
安装及配置方法如下,假设web服务器根目录为/opt/htdocs
cd /opt/htdocs
git clone https://github.com/EvaEngine/xhprof.io.git
cd xhprof.io/
composer install
cp xhprof/includes/config.inc.sample.php xhprof/includes/config.inc.php
vi xhprof/includes/config.inc.php
在MySQL中建立xhprof.io数据库,假设数据库名为xhprof
,然后导入xhprof/setup/database.sql
配置文件config.inc.php
中需要调整
'url_base' => 'http://localhost/xhprof.io/',
这是xhprof.io界面所在路径'pdo' => new PDO('mysql:dbname=xhprof;host=localhost;charset=utf8', 'root', 'password'),
根据MySQL实际情况调整配置enable
这是一个匿名函数,当匿名函数返回true时启用xhprof数据收集
通过配置enable
项,就可以实现线上调试的需求,比如
始终开启xhprof
'enable' => function() {
return true;
}
1/100概率随机开启xhprof
'enable' => function() {
return rand(0, 100) === 1;
}
网页携带参数debug=1时开启xhprof
'enable' => function() {
return !empty($_GET['debug']);
}
网页URL为特定路径时开启
'enable' => function() {
return strpos($_SERVER['REQUEST_URI'], '/testurl') === 0;
}
最后按上文所述,在要配置的项目中包含xhprof.io/inc/inject.php
即可。
线上环境操作时务必要胆大心细,如果没有结果尤其注意需要检查xhprof扩展是否安装。
附录:xhpgui的安装方法
apt-get install mongodb php5-mongo php5-mcrypt
cp /etc/php5/mods-available/mcrypt.ini /etc/php5/fpm/conf.d/
cp /etc/php5/mods-available/mcrypt.ini /etc/php5/cli/conf.d/
cd /opt/htdocs
git clone https://github.com/perftools/xhgui.git
cd xhgui
composer install
cp config/config.default.php config/config.php
chown www-data.www-data -R cache
编辑Nginx配置文件加入
fastcgi_param PHP_VALUE "auto_prepend_file=/opt/htdocs/xhgui/external/header.php";
收集数据过多时可以清空mongodb
mongo
use xhprof;
db.dropDatabase();
PHP性能监控的更多相关文章
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- jvm系列(五):tomcat性能调优和性能监控(visualvm)
tomcat服务器优化 1.JDK内存优化 根据服务器物理内容情况配置相关参数优化tomcat性能.当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃.因此一般建议堆的最 ...
- spring拦截器 实现应用之性能监控
package cn.ximi.erp.web.common.interceptors; import cn.ximi.core.common.utils.string.StringUtil; imp ...
- Performance Monitor1:开始性能监控
Performance Monitor是Windows内置的一个可视化监控工具,能够在OS级别上实时记录系统资源的使用情况,通过收集和存储日志数据,在SQL Server发生异常时,能够还原系统当时的 ...
- 前端性能监控方案window.performance 调研(转)
1. 业界案例 目前前端性能监控系统大致为分两类:以GA为代表的代码监控和以webpagetest为代表的工具监控. 代码监控依托于js代码并部署到需监控的页面,手动计算时间差或者使用浏览器的的API ...
- Apache服务器性能监控
Apache服务器性能监控 1.使用自带mod_status模块监控 1)加载mod_status.so 模块 在httpd.conf中打开LoadModule status_module modul ...
- jvm性能监控与故障处理工具
jdk为我们提供了一系列的jvm性能监控和故障处理工具,在这里根据学习进度进行整理记录.便于之后查阅 1.jps 虚拟机进程工具 类似于Linux系统中的ps命令,用于查看虚拟机进程,常用的有以下功 ...
- [整]磁盘 I/O 性能监控指标和调优方法
在介绍磁盘 I/O 监控命令前,我们需要了解磁盘 I/O 性能监控的指标,以及每个指标的所揭示的磁盘某方面的性能. 磁盘 I/O 性能监控的指标主要包括: 指标 1:每秒 I/O 数(IOPS 或 t ...
- cAdvisor0.24.1+InfluxDB0.13+Grafana4.0.2搭建Docker1.12.3 Swarm集群性能监控平台
目录 [TOC] 1.基本概念 既然是对Docker的容器进行监控,我们就不自己单独搭建cAdvisor.InfluxDB.Grarana了,本文中这三个实例,主要以Docker容器方式运行. 本 ...
- NanoProfiler - 适合生产环境的性能监控类库 之 基本功能篇
背景 NanoProfiler是一个EF Learning Labs出品的免费性能监控类库(即将开源).它的思想和使用方式类似于MiniProfiler的.但是,设计理念有较大差异. MiniProf ...
随机推荐
- 【JZOJ4858】【GDOI2017模拟11.4】Walk
题目描述 在比特镇一共有n 个街区,编号依次为1 到n,它们之间通过若干条单向道路连接. 比特镇的交通系统极具特色,除了m 条单向道路之外,每个街区还有一个编码vali,不同街区可能拥有相同的编码.如 ...
- 软件测试 → 第二章 基础-> 软件缺陷与缺陷管理
一.缺陷定义与分类 1.1.软件缺陷 定义:在软件工程整个生命周期中任何背离需求.无法正确完成用户所要求的功能的问题,包括存在于组件.设备.或系统软件中因异常条件不支持而导致系统失败等都属于缺陷. 从 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION) 学习目标 ...
- Effective C++: 08定制new和delete
49:了解new-handler的行为 当operator new无法满足某一内存分配需求时,它会抛出异常(以前会返回一个null).在抛出异常之前,它会调用一个客户指定的错误处理函数,也就是所谓的n ...
- PLAY2.6-SCALA(六) 异步处理结果
1.创建异步的controller Play是一个自底向上的异步框架,play处理所有的request都是异步.非阻塞的.默认的方式是使用异步的controller.换句话说,contrller中的应 ...
- PHP:测试SQL注入以及防止SQL注入
在写登录注册的时候发现了SQL和JS注入这个危害网站的用户举动: 测试方法: SQL注入: 先来做一个测试: 用户名:’ or 1 # 密码:随便写8位以上 验证码:写正确 好吧,就那么简单就进去了: ...
- shell学习(23)- diff和patch
diff命令可以生成两个文件之间的差异对比. (1) 先创建下列用于演示的文件.文件 1:version1.txt this is the original text line2 line3 line ...
- 解决PowerDesigner中DBMS选项卡为空白
点击DBMS后面的黄色(浏览)文件图标, 找到安装目录里面PowerDesigner \Resource Files\DBMS,就可以了.
- BZOJ5259/洛谷P4747: [Cerc2017]区间
BZOJ5259/洛谷P4747: [Cerc2017]区间 2019.8.5 [HZOI]NOIP模拟测试13 C.优美序列 思维好题,然而当成NOIP模拟题↑真的好吗... 洛谷和BZOJ都有,就 ...
- java 读取文内容(text,html)
1.将前端上传的html文件全部读取出来,并用string字符串返回出去解析的内容 public static String openFile(MultipartFile file) { try { ...