着业务复杂度的增加,PHP 的性能问题越来越明显。为了提升 PHP 的性能,开发人员通常会利用各种性能分析工具。
xhprof 是优秀的性能分析 PHP 扩展,它能收集程序运行时函数调用信息和内存使用情况,帮助开发者发现性能瓶颈。
引用官方的描述,我做了中文翻译:
XHProf 是 PHP 的函数级分层分析器,具有一个简单的基于 HTML 的导航界面。
原始数据收集组件是用 C 语言实现的(作为 PHP 扩展),报告/UI 层全部使用 PHP。
它能够报告函数级别的非独占和独占实际时间、内存使用情况、CPU 时间和每个函数的调用次数。
此外,它还支持比较两次运行(分层 DIFF 报告)或聚合多次运行的结果。
本文将详细介绍如何使用 xhprof 对 PHP 进行性能优化,包括 xhprof 的安装与配置、使用方法、性能分析指标以及在实际项目中的应用。
安装和配置
xhprof 支持 PHP7.2 以上的版本,可以在以下地址下载(我使用的是 2.3.10 版本):
- GitHub: github.com/longxinH/xh…
- PECL: pecl.php.net/package/xhp…
下载后解压,进入目录编译安装:
cd xhprof/extension/
/path/to/php7/bin/phpize
./configure --with-php-config=/path/to/php7/bin/php-config
make && sudo make install
然后修改php.ini
文件,文件末尾添加以下内容:
[xhprof]
extension=xhprof.so
xhprof.output_dir=/tmp/xhprof
不要忘记重启您的 php-fpm
让扩展生效。如果您不确定是否安装,可以执行以下命令确认:
php -m
php --ri xhprof
准备探针项目
我们可以新建 xhprof.test.com
工程,加入 xhprof_html
和 xhprof_lib
目录,并新增 php72.php
文件:
xhprof/xhprof_html/... PS: 来自源码包
xhprof/xhprof_lib/... PS: 来自源码包
xhprof/php72.php
探针文件 php72.php(可根据实际需要修改):
<?php
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();
}
include_once dirname(__FILE__) . '/xhprof_lib/utils/xhprof_lib.php';
include_once dirname(__FILE__) . '/xhprof_lib/utils/xhprof_runs.php';
$xhprof_runs = new \XHProfRuns_Default();
$xhprof_runs->save_run($xhprof_data, 'xhprof');
});
部署可视化工具
探针准备好了之后,我们继续部署可视化工具。
xhprof 提供了一个开箱即用的 Web UI——没错,就是源码包下的 xhprof_html 目录。
它的原理是在引入上述的探针文件 php72.php 后,运行我们的代码,扩展会写入性能分析数据到 php.ini 里面配置的 output_dir 目录(/tmp/xhprof)中。
此时 Web UI 读取并解析该目录,调用 graphviz 项目生成图片,渲染展示到浏览器上。
我们需要将 xhprof.test.com
和 待性能分析的项目一起部署。
推荐在开发或者测试环境部署,不建议生产环境使用,避免影响到生产环境的业务。
我基于 docker-compose 搭建了一套开发测试环境, 集成了 nginx + PHP7 环境,而 xhprof UI 的运行,需要提前安装 graphviz 项目,这里以 CentOS 为例:
yum install graphviz -y
配置好 nginx 的 vhost,root 指向 xhprof_html 目录,我们就可以开始定位问题了!
如何定位问题
假设我们现在要定位 Laravel 项目的控制器某个函数的性能问题(接口非常慢)!
如某项目的某个接口,有时候要 几十秒
才返回,单纯看代码(大几千行)非常难定位原因!
这个时候我们引入上面的项目文件:
class TestController extends Controller
{
// ...
public function getInfo(Request $request)
{
// 此处引入一行代码即可
require_once '/path/to/xhprof.test.com/xhprof/php72x.php';
// ...
// 业务逻辑巴拉巴拉
}
// ...
}
访问 xhprof.test.com 我们可以得到这个图:
点击 [View Full Callgraph]
可以获取调用图,图中可以看到,
接口在最后请求了 App\Service\DataSystem\xxxxx::yy
函数,
最后在 curl_exec
耗时 40s
!!!
查询函数调用的上下文,第一眼就可以定位出是获取某数据耗时很长(这里打了马赛克,实际项目会展示完整的函数名称)!
翻查代码后发现,接口依赖的下游(curl_exec 耗时 40s)确实存在问题,修复后就恢复正常了!
总结
总的来说,xhprof 是一个强大的 PHP 性能分析扩展,通过它,我们可以快速定位并解决 PHP 程序中的性能问题。
它不仅提供了详尽的性能数据,还通过可视化工具帮助我们直观地理解程序的运行状况。在实际应用中,xhprof 可以帮助我们识别出代码中的性能瓶颈,从而进行针对性的优化。
扩展阅读
对于想要深入了解 xhprof 的用户,可以阅读官方文档,了解更多关于 xhprof 的高级特性和最佳实践。
此外,还可以探索其他 PHP 性能分析工具,如 xhgui + tideways,它们也提供了更加美观大方的 UI 和更强大的性能分析功能!
通过结合使用不同的工具,我们可以更全面地了解应用程序的性能状况,并采取有效的优化措施。