剖析是一种用来观察程序性能的技术,非常适合于发现程序的瓶颈或资源紧张的情况。概要分析可以深入到程序中,显示请求处理过程中代码各部分的性能;同时,也可以确定有问题的请求;对于有问题的请求,我们还可以确定请求中出现性能问题的地方。对于PHP,我们有各种Profiling工具,本文重点介绍——XHGui,一个非常好的工具。XHGui建立在XHProf之上(XHProf由脸书出版),但它为分析结果增加了更好的存储和更好的信息获取界面。在这方面,XHGui更像是一个全新的工具。
XHGui经历了几次迭代,但当前版本提供了更漂亮的用户界面,并使用MongoDB存储其解析结果。与之前的版本相比,所有这些方面都是巨大的改进;因为之前的版本更像是开发者的设计,用文件保存数据,这就使得收集到的数据非常难以使用。XHGui 2013是一个非常全面的Profiling工具,无论是对于经理还是开发人员;同时,XHGui 2013设计得足够轻,可以在生产环境中运行。
本文将逐步演示程序的安装,并向您展示使用该工具可以收集的各种信息。
步骤1:安装依赖项
因为XHGui有一些依赖性,我们的第一步就是解决这个问题。以下所有教程均基于Ubuntu 13.04平台。当然,您应该能够适应它们,并将其应用到您自己的平台上。目前我们需要安装MongoDB、PHP,并且有一定能力安装PECL扩展。
首先,我们要安装MongoDB。这里有一些官方安装教程。您可以找到与您的系统相关的详细信息,但现在我将简单地通过APT安装它:
通过这种方式获得的智能安装MongoDB的版本可能不是最新的,因为这款产品的更新速度真的很快。但是,如果您希望它保持一个非常新的版本,您可以将MongoDB提供的库添加到您的包管理器中,这样您就可以获得最新的版本。
同时,我们还需要针对PHP的Mongo驱动程序。仓库里这个驱动的版本有点旧了。对于今天的演示,我们将从Pecl获得它。如果您的计算机上没有pecl命令,您可以使用以下命令安装它:
智能安装php-pear然后,我们通过以下命令向php添加MongoDB驱动程序:
Pecl install mongo为了完成安装,我们最后需要在php.ini文件中添加一个新的行。但是新版本的Ubuntu提供了一个配置PHP扩展的新系统,更像是Apache模块安装——,将所有配置保存在一个地方,然后创建一个符号链接开始配置。首先,我们创建一个文件来保存设置,尽管在这个例子中,我们只需要在设置中添加一个新行来启动扩展。我们将其保存在文件/etc/PHP 5/MODS-available/mongo . ini中,并添加以下行:
Php5enmod mongo再次使用pecl安装xhprof扩展。目前这个程序只是beta版本,所以安装命令如下:pecl install xhprof-beta命令行会提示我们再次在php.ini中添加新的一行。和上面一样,我们创建了文件/etc/PHP 5/MODS-available/xh prof . ini,并在里面添加了以下内容:
所以此时,我们可以检查这些模块是否安装正确。通过在命令行上运行php -m命令。记住,不要忘记重启Apache,这样web界面就可以启用这些扩展。安装XHGui
XHGui本身主要由网页组成,为XHProf扩展收集的数据提供了更友好的界面。可以从代码库中克隆GitHub repo也可以直接下载zip文件并解压。获取程序后,确保缓存目录有足够的权限,以便web服务器有权限写入文件。最后,运行安装脚本:
PHP install.php这是程序安装所需要的一切,并且会自动安装一些相关的程序;如果出现问题,安装程序会提示您。
我更喜欢在虚拟主机中安装XHGui这需要得到。htaccess文件,还需要启动RUL重写。开始网址重写表示需要通过以下命令启动mod _ rewrite模块:
A2enmod重写(别忘了重启Apache)。如果一切顺利,您可以正常访问XHGui的URL,并看到以下内容:
在虚拟主机中启动XHGui
在这一点上,我们想要启动XHGui来测试我们网站的性能。注意,最好在任何优化之前进行一次性能测试,以测试优化的效果。最简单的方法是在虚拟主机中添加auto_prepend_file声明,如下图所示:
VirtualHost *:80 ServerName示例. local document root/var/www/example/htdocs/PHP _ admin _ value auto _ prepend _ file/var/www/xhgui/external/Header.php目录/var/www/example/htdocs/options跟在symlinks后面索引允许覆盖all/directory/virtual host一切准备就绪后,就可以开始分析网站请求了。xgui只能分析1%的网站请求,所以为了让xgui获得有意义的数据,需要让xgui运行一段时间或者使用Apache Bench这样的测试工具提交一批请求。为什么XHGui只解析100个请求中的一个?因为XHGui最初被设计得足够轻,可以在生产环境中使用,所以它不想为每个请求产生额外的开销,1%的采样率已经可以提供网站整体流量的清晰概览。
满足数据
我使用测试虚拟机运行本文中的所有示例,并使用Joind.in API作为测试代码。为了产生一些流量,我运行了几次API测试用例。你也可以在一定的负载下收集数据,所以你可以在压力测试中使用XHGui,甚至可以在在线网站中使用XHGui收集数据(听起来很疯狂,但是脸书官方为这个应用开发了这个工具)。向应用程序发送某个请求后,重新访问XHGui,现在它已经保存了一些数据:
该图向我们显示了XHGui分析的每个请求,最新的请求排在第一位,并且为每个请求显示了一些附加信息。这些信息包括:
URL:请求访问的URL时间:请求启动时间wtor:' wall Time '请求经过的所有时间。这是“挂钟”时间的缩写,意思是用户等待请求完成的所有时间。cpu:花费在请求上的CPU时间mu:请求消耗的内存pmu:请求处理期间消耗的最大内存。有关每个请求(“运行”)的更多详细信息,您可以单击网址获取该网址所有请求的详细信息。无论哪种方式,您都可以获得关于请求的更详细信息:
这是一个非常长且详细的页面,所以我引用了两个截图(如果显示所有信息,需要五个截图)。上图左边部分显示了一些与请求相关的信息,以帮助您跟踪这些统计数据与哪些方面相关;右边的主要部分显示了请求过程中最耗时的部分和每个函数调用消耗的内存。图形底部有一个主键来指示每一列。
第二个图显示了关于请求的每个组件的更详细的信息。我们可以看到各个部分的调用次数和时间消耗,包括CPU和内存信息。包含信息和排他信息都有详细的展示:排他指的只是方法调用产生的消耗;includes不仅包括该函数产生的消耗,还包括该函数调用的其他函数产生的消耗。
XHGui的另一个特性是Callgraph,它以生动而虚拟的方式显示了时间是如何消耗的:
这是函数调用层次结构的一个很好的例子。最重要的是,该图是交互式的,您可以拖放它来更好地查看连接。您也可以使用鼠标在斑点上滑动来查看更多信息。当你和它互动时,它会在乐趣中弹跳和移动,这不是一个很重要的功能,但它让我觉得很有趣。
了解数据
有大量的统计数据很重要,但很难知道从哪里开始。对于性能不如预期的页面,采取以下步骤:首先,对每个函数的独占CPU时间进行排序,查看最耗时的函数列表。分析这些耗时的函数调用,并对其进行重构和优化。
修改完成后,让分析工具再次检查程序的新版本,以测试性能改进。XHGui内置了比较两次运行的完美工具;单击详细信息页面右上角的“比较本次运行”按钮。此按钮将向您显示此网址的每次测试结果,并选择您要比较的对象。点击你想要比较的对象的“比较”按钮,XHGui会转到比较视图,如下图所示:
统计表显示了新版本和旧版本之间的主要差异,包括每次信息更改的实际数量和百分比。上图显示,新版本的请求等待时间仅为旧版本的8%。统计表详细展示了每一个统计信息的变化,这一点我们经常可以在“详细信息”页面看到;您可以对任何列进行排序,以找到您感兴趣的信息。
一旦在一个方面成功重构,检查详细信息页面以检查新版本的实际效果,然后选择其他方面进行优化。尝试对内存使用或独占挂壁时间进行排序,从而选择能够最大化应用整体性能的功能进行优化。同时,不要忘记检查电话号码。重复调用的函数可以在优化后指数级提高程序的性能。
优化方法
在量化结果之前,你很难知道你已经改进了多少,这就是为什么我们经常在优化应用程序之前测试它——否则,你怎么知道你是否真的优化了它?我们还需要思考一组真实的数据应该如何表达,否则,我们可能会朝着一个不可能的目标前进。一个非常有用的方法是试图找到最合适的数据结构和最小的存储空间。如果你不能在你擅长的工作环境中在半秒钟内运行一个“Hello world”程序,不要指望用同样的工具构建的网页能表现出色。
以上说法并不是对编程框架的不尊重;编程框架的存在是因为它易于使用,支持快速开发,易于维护。与手工编写代码相比,编程框架的性能下降是我们之间妥协的结果。使用编程框架进行应用程序开发是尽快上线的好方法。必要时,您可以使用分析工具来分析和提高程序的性能。比如Zend Framework 1的很多模块可以提供不强大的功能,但是可以很低;使用分析工具,您可以识别性能不佳的零件并替换它们。所有其他框架都有类似的问题。XHGui可以向您显示问题,并检查它们是否对您的程序有可量化的影响。
在你的计划之外,一些其他的策略可能有助于你迟早占据上风。
注意页面上出现的不是危险、缓慢但相关的功能。如果您的页面将50%的时间花在视图助手中的一系列函数上(我保证这是一个假设的例子),那么您可能想要研究重构整个组件。少做。如果性能比功能更重要,请尝试删除功能。请注意在请求中生成但未在特殊视图中使用的内容,或者未更改但多次重新生成的内容。好的缓存策略。这将是关于它的另一篇文章,但是考虑在PHP中使用一个OpCode缓存(从PHP 5.5中内置),在您的web服务器前面添加一个反向代理,并简单地为那些不常更改的内容发送适当的缓存头。暴力脱钩。如果有一个资源严重短缺的特殊功能,把它从你的网络服务器上删除。也许它可以异步处理,所以您的程序可以只向队列中添加一条消息,或者移动到另一个单独的服务器,并作为一个单独的服务模型来访问它。无论哪种方式,分离都有助于减少web服务器上的负载,并实现有效的扩展。XHGui是你的朋友
XHGui安装简单,使用方便,输出优秀,可以在董事会上展示。它可以识别我们应用程序中的错误,并帮助我们确认应用程序是否真的工作(或者不工作!)。这可能会经历一些重复的过程,但无论您之前是否使用过XHProf或XHGui,我都建议您花一些时间来尝试您的应用程序,您会对您的发现感到惊讶。