PHP 性能分析第一篇: Intro to Xhprof & Xhgui
【前言】这是国外知名博主 Davey Shafik所撰写的 PHP 应用性能分析系列的第一篇,阅读第二篇可深入了解 xhgui,第三篇则关注于性能调优实践。
原文链接如下:
https://blog.engineyard.com/2014/profiling-with-xhprof-xhgui-part-1
https://blog.engineyard.com/2014/profiling-with-xhprof-xhgui-part-2
https://blog.engineyard.com/2014/profiling-with-xhprof-xhgui-part-3
http://blog.csdn.net/heiyeshuwu/article/details/49512527
什么是性能分析?
性能分析是衡量应用程序在代码级别的相对性能。性能分析将捕捉的事件包括:CPU的使用,内存的使用,函数的调用时长和次数,以及调用图。性能分析的行为也会影响应用性能。

影响的程度取决于基准测试。基准测试在外部执行,用于衡量应用真实性能。所谓真实性能,即终端用户所体验的应用表现。
什么时候应该进行性能分析?
在考虑是否进行性能分析时,你首先要想:应用是否存在性能问题?如果有,你要进一步考虑:这个问题有多大?
如果你不这样做,将会陷入一个陷阱——过早优化,这可能会浪费你的时间。
为了评断应用是否存在性能问题,你应该确定性能目标。例如,100个并发用户的响应时间小于1s。然后,你需要进行基准测试,看是否达到这个目标。一个常见的错误是,在开发环境进行基准测试。事实上,你必须在生产环境进行基准测试。(实际生产环境或模拟的生产环境,后者很容易在 SaaS 实现(例如:OneAPM PHP应用性能在线分析示例)。
用于基准测试的产品很多,包括 ab,siege 和 JMeter。我个人比较喜欢JMeter的功能集,但 ab 和 siege 更加易用。
一旦你确定应用存在性能问题,就需要分析其性能,实施改进,然后再一次进行基准测试,查看问题是否解决。每一次变更之后,你都该进行基准测试查看效果。如果你做了很多变更,却发现应用性能有所下降,你就无法确定具体是哪一次变更导致了这个问题。
下图是我定义的性能生命周期:

性能下降的一般原因
导致性能下降的一般原因中,有些相当出人意料。即便是像 PHP 这样的高级语言,代码的好坏也很少是问题的根源。在当今的硬件配置条件下,CPU 很少是性能限制的原因。常见的原因反而是:
数据存储
- PostgreSQL
- MySQL
- Oracle
- MSSQL
- MongoDB
- Riak
- Cassandra
- Memcache
- CouchDB
- Redis
外部资源
- APIs
- 文件系统
- 网络接口
- 外部流程
糟糕的代码
选择哪一种性能分析器?
在 PHP 世界里,有两个截然不同的的性能分析器——主动和被动。
主动 VS 被动性能分析
主动分析器在开发过程中使用,由开发人员启用。主动分析器收集的信息比被动分析器多,对性能的影响更大。通常,主动分析器不能用在生产环境中。Xdebug 就是一种主动分析器。
因为无法在生产环境中使用主动分析器,Facebook 推出了一个被动分析器——XHprof。XHprof 是为了在生产环境中使用而打造的。它对性能的影响最小,同时收集足够的信息用于诊断性能问题。XHprof 和 OneAPM 都是被动分析器。
通常,Xdebug 收集的额外信息对于一般的性能问题分析并不必要。这意味着,被动分析器是用于不间断性能分析的更佳选择,即使是在开发环境中。
Xhprof + Xhgui
Xhprof 由 Facebook 开发的,包含一个基本的用户界面用于查看性能数据。此外,Paul Reinheimer 开发了 Xhgui 和一个增强的用户界面(UI)用于查看、比较和分析性能数据。
安装
安装 XHPROF
Xhprof 可通过 PECL 安装,步骤如下:
$pecl install xhprof-beta
该 pecl 命令将尝试自动更新你的 php.ini 设置。pecl 尝试更新的文件可以使用以下命令找到:
$ pecl config-getphp_ini
它会在指定的文件(如果有的话)顶部增加新的配置行。你可能想把他们移到一个更合适的位置。
一旦你编译了该扩展程序,您必须启用它。为此,您需要在 PHP INI 文件添加以下代码:
[xhprof]
extension=xhprof.so
之后,结合 Xhgui 就能轻松地执行性能分析与检查。
安装 XHGUI
安装 Xhgui,必须直接从 git 获取。该项目可以在 github 上找到,地址为https://github.com/perftools/xhgui
Xhgui 要求:
- PHP 5.3+
- ext/mongo
- composer
- MongoDB(若只需要收集数据,则可选可不选;若需要数据分析,则为必选)
首先,克隆项目到任意位置。在基于 Debian 的 Linux 系统(例如 Ubuntu 等等),可能是 /var/www。在 Mac OS X 系统,可能是 /Library/WebServer/Documents。
$cd /var/www
$ git clone https://github.com/perftools/xhgui.git
$ cd xhgui
$ php install.php
最后一个命令是运行 composer 以安装依赖并检查 xhgui 缓存目录的权限。如果失败,你可以手动运行 composer install。
下一步,你可能需要创建配置文件。这一步很容易实现,可以使用在 /path/to/xhgui/config/config.default.php 下的默认配置文件。
如果你在本地运行 mongodb ,没有身份验证,则可能不需要这样做。因为它将回退为默认值。而在多服务器环境中,你会需要一个所有服务器都能进行存储的远程 mongodb 服务器,并进行恰当的配置。
为提高 MongoDB 的性能,你可以运行以下指令以添加索引:
$ mongo
> use xhprof
db.results.ensureIndex( {'meta.SERVER.REQUEST_TIME': -1} )
db.results.ensureIndex( {'profile.main().wt': -1} )
db.results.ensureIndex( {'profile.main().mu': -1} )
db.results.ensureIndex( {'profile.main().cpu': -1} )
db.results.ensureIndex( {'meta.url':1} )
其他配置
如果你不想在生产环境中安装 mongo ,或无法让 Web 服务器访问 mongo 服务器,您可以将性能分析数据保存在磁盘中,再导入到本地MongoDB 供以后分析。
为此,请在 config.php 中进行以下修改:
'save.handler' = 'file',
'save.handler.filename' => '/path/to/xhgui/xhprof-' .uniqid("", true). '.dat',
改变文件中的 save.handler,然后取消批注 save.handler.filename ,为其赋一个恰当的值。
注意:默认每天只保存一个分析文件。
一旦分析数据的准备就绪,你就可以使用 xhgui 附带的脚本导入之:
$php import.php -f /Users/baidu/Downloads/xhgui-data.bat
在此之后的步骤都相同。
运行 Xhgui
Xhgui 是以 PHP 为基础的 Web 应用程序,你可以以 /path/to/xhgui/webroot为根文件,设置一个标准的虚拟主机。
或者,你可以简单地使用 PHP 5.4 + cli-server 例如:
$cd/path/to/xhgui
$ php -S0:8080-t webroot/
这将使 Xhgui 在所有网络接口都可通过 8080 端口进行通信。
运行性能分析器
运行分析器时,你需要在待分析的所有页面包含 external/header.php 脚本。为此,你可以在 PHP ini 文件设置 auto_prepend_file 。你既可以直接在公共 INI 文件进行设置,也可以限制到单一的虚拟主机。
对于 Apache 服务器,添加以下代码:
php_admin_value auto_prepend_file "/path/to/xhgui/external/header.php"
对于 Nginx 服务器,在服务器配置中添加以下代码:
fastcgi_param PHP_VALUE "auto_prepend_file=/path/to/xhgui/external/header.php";
如果您使用 PHP 5.4 + cli-server(PHP - S),则必须通过命令行标记进行设置:
$ php -S 0:8080 -dauto_prepend_file=/path/to/xhgui/external/header.php
默认情况下,分析器运行时只分析(大约)1%的请求。这是由以下 external/header.php 代码控制的:
if (rand(0, 100) !== 42) {
return;
}
如果你想分析每一个请求(例如,在开发阶段),你可以将这段代码注释掉。如果你想让分析10%的请求,你可以做如下改动:
if (rand(0, 10) !== 4) {
return;
}
这允许你对一小部分用户请求进行分析,而不过多影响单个用户或太多用户。
如果你想在性能分析时进行手动控制,你可以这样做:
if (!isset($_REQUEST['A9v3XUsnKX3aEiNsUDZzV']) && !isset($_COOKIE['A9v3XUsnKX3aEiNsUDZzV'])) {
return;
} else {
// Remove trace of the special variable from REQUEST_URI
$_SERVER['REQUEST_URI'] = str_replace(array('?A9v3XUsnKX3aEiNsUDZzV', '&A9v3XUsnKX3aEiNsUDZzV'), '', $_SERVER['REQUEST_URI']);
setcookie('A9v3XUsnKX3aEiNsUDZzV', 1);
}
if (isset($_REQUEST['no-A9v3XUsnKX3aEiNsUDZzV'])) {
setcookie('A9v3XUsnKX3aEiNsUDZzV', 0, time() - 86400);
return;
}
这段代码会检查一个随机命名的 GET/POST/COOKIE 变量(在此例中为:A9v3XUsnKX3aEiNsUDZzV),同时创建一个同名的 Cookie ,用于分析该请求的整个过程,例如:表单提交后的重定向,Ajax 请求等等。
此外,它允许一个名为 no-A9v3XUsnKX3aEiNsUDZzV 的 GET/POST 变量来删除 cookie ,停止分析。
PHP 性能分析第一篇: Intro to Xhprof & Xhgui的更多相关文章
- PHP 性能分析第一篇: Xhprof & Xhgui 介绍
[前言]这是国外知名博主 Davey Shafik所撰写的 PHP 应用性能分析系列的第一篇,阅读第二篇可深入了解 xhgui,第三篇则关注于性能调优实践. 什么是性能分析? 性能分析是衡量应用程序在 ...
- Windows系统CPU内存网络性能统计第一篇 内存
最近翻出以前做过的Windows系统性能统计程序,这个程序可以统计系统中的CPU使用情况,内存使用情况以及网络流量.现在将其整理一下(共有三篇),希望对大家有所帮助. 目录如下: 1.<Wind ...
- PHP 性能分析第二篇: Xhgui In-Depth
[前言]这是国外知名博主 Davey Shafik 撰写的 PHP 应用性能分析系列的第二篇,第一篇介绍 Xhprof/Xhgui,第三篇则关注于性能调优实践. 在第一篇中,我们初步介绍了 xhpro ...
- 转 web前端性能分析--原理篇
转自http://blog.csdn.net/five3/article/details/7686715 web前端性能: 即是web用户在访问一个页面时所要花费的时间总和.即一个完全意义上的用户响应 ...
- jrtplib源码分析 第一篇 jthread的编译与分析
第一篇 jthread的编译与分析 jrtplib代码依赖库jthread,因此先从jthread开始jrtplib的学习.首先从以下链接下载jthread的源代码http://research.ed ...
- MySQL监控、性能分析——工具篇
https://blog.csdn.net/leamonjxl/article/details/6431444 MySQL越来越被更多企业接受,随着企业发展,MySQL存储数据日益膨胀,MySQL的性 ...
- 转 WEB前端性能分析--工具篇
在线网站类: WebPageTest 说明: 在线的站点性能评测网站,地址http://www.webpagetest.org/ 补充: 其实这网站也是个开源项目,所以支持自己搭建一个内部的测试站点 ...
- MySQL监控、性能分析——工具篇(转载)
MySQL越来越被更多企业接受,随着企业发展,MySQL存储数据日益膨胀,MySQL的性能分析.监控预警.容量扩展议题越来越多.“工欲善其事,必先利其器”,那么我们如何在进行MySQL性能分析.监控预 ...
- ansible代码分析第一篇--主文件—ansible分析
2016年2月23日,学习,分析ansible代码 ansible是一种运维中使用的批量部署的工具,它本身是一种框架,具体的部署和架构分析,下面这篇文章讲的不错. http://os.51cto.co ...
随机推荐
- Netty源码分析第5章(ByteBuf)---->第8节: subPage级别的内存分配
Netty源码分析第五章: ByteBuf 第八节: subPage级别的内存分配 上一小节我们剖析了page级别的内存分配逻辑, 这一小节带大家剖析有关subPage级别的内存分配 通过之前的学习我 ...
- 2019第十届蓝桥杯C++B组题解(赛后重写的,不确保答案正确性,仅供参考)
先说一下这次的感受吧,我们考场比较乱,开始比赛了,还有的电脑有故障,(向这些人发出同情),第一次认真参加比赛,真正比赛的时候感觉没有那么正式,很乱,各种小问题,(例如博主就没找到题目在哪里,找到后又不 ...
- dp算法之有代价的最短路径
题目:有代价的最短路径 题目介绍:如下图所示,现在平面上有N个点,此时N=7,每个点可能和其他点相连,相连的线有一定权值,求出从0点到N-1点的消耗权值的最小值. 分析:用动态规划的思路来解决,每一点 ...
- caffe/blob.hpp:9:34: fatal error: caffe/proto/caffe.pb.h: 没有那个文件或目录
You need to generate caffe.pb.h manually using protoc as follows. # In the directory you installed C ...
- ahk打印成pdf记录
软工课程后记: 要求将博客打印成pdf存档.为了偷懒,不想自己点鼠标一个个保存,所以写了一个ahk小程序.博客教程推荐,建议一试,不难.还很方便.我也只学了点点皮毛,满足需求即止. 第一个成功的小例子 ...
- 软件工程第十周psp
1.PSP表格 2.进度条 3.饼状图 4.折线图
- No.1010_第七次团队会议
渺茫的前景 今天大家都很失望,一来昨天的问题还是继续存在着,仍然没有完成.二来,我们看了一下其余几个组的界面,对自己有些难过. 我们组确实存在人手少的问题,这几天我还因为挑战杯的事情缺席了两天,感觉内 ...
- Struts2框架学习
Struts功能详解——ActionMapping对象 ActionMapping描述了struts中用户请求路径和Action的映射关系,在struts中每个ActionMapping都是通过pat ...
- Javascript面向对象二
Javascript面向对象二 可以通过指定原型属性来对所有的对象指定属性, Object.prototype.name="zhangsan"; Object.prototype. ...
- HDU 1565 方格取数(1) 轮廓线dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) ...