预计阅读时间: 7 分钟
对于生产环境下php响应缓慢的问题,一般我们可以把分析流程拆分为如下几步操作:
1.分析开发环境下执行是否会慢;
如果是代码问题,在开发环境下就能检测出来;
2.分析测试机器执行是否会慢;
如果是数据库或者第三方扩展问题,在测试阶段就能检查出来。
3.从生产环境下线一台机器,分析代码执行慢的原因;
如果是机器的问题,在这一步才能检查出来。
1,2,3步骤都需要去分析代码,看哪部分执行时间长。如果迫不得已在生产环境下调试代码,不但要耗费大量时间还可能导致用户流失。
大多时候我们会使用第三方的分析工具xhprof来快速发现问题。xhprof是由facebook开发的一款非侵入式php性能分析框架。但是官方已经不在维护,也没有跟进php7,只能在php5上运行,tideways则是一直由商业公司在xhprof停止维护后fork出的版本,开源在Github上(托管服务需付费,自行搭建免费),支持PHP7。显而易见,tideways是我们的选择。
tideways扩展能把每条请求生成详细的执行日志,通过对日志做简单的分析就能看到程序哪部分耗时最长,这里可以使用xhprof的UI程序(xhprof生成的日志和tideways生成的日志格式通用),交互虽然不大友好但是够用了。当然,也可按照本文介绍使用xhgui来进行可视化的分析。
先决条件
本文部署所用环境为Ubuntu 18.04 LTS,其它环境请自行研究类似的配置。
安装Tideways
由于部署环境php采用编译安装,故Tideways也采用编译安装。如果采用apt安装,也可以直接使用apt安装php-tideways。还可以使用pecl安装,具体方法不详细讲了。
git clone https://github.com/tideways/php-xhprof-extension
cd php-xhprof-extension phpize ./configure make make install //sudo make install if not root
配置php.ini,加入
extension=tideways_xhprof.so tideways.auto_prepend_library=0 //optional
注意最好加上后面那行,因为如果不加,tideways会调试所有经过php-fpm的请求,包括xhgui的请求,而这些请求不是我们想看的。
安装xhgui
其实xhgui就是一个网站程序,建过站的同学都知道大概怎么回事,只不过数据库换用了mongodb而已。
安装mongodb
因为xhgui需要储存由tideways传入的信息,所以需要安装mongodb。另有人维护了一个mysql版本的xhgui,如果不喜欢mongodb可以换用。部署环境使用了oneinstack安装lnmp栈,所以也使用oneinstack安装mongodb
wget http://mirrors.linuxeye.com/oneinstack.tar.gz tar zxf oneinstack.tar.gz
cd oneinstack ./install.sh // sudo install.sh if not root
按照提示交互式安装mongodb就行了。如果你不想这么麻烦或者非生产环境部署,也可以直接使用apt安装:apt install mongodb
如果没有在php中加入mongodb扩展,则需继续安装mongodb扩展。
git clone https://github.com/mongodb/mongo-php-driver.git
cd mongo-php-driver
git submodule update --init phpize ./configure make make install // add sudo if not root >
同样地,在php.ini中添加extension=mongodb.so
官方基于性能建议我们为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 } ) >
db.results.ensureIndex( { 'meta.simple_url' : 1 } )
至此mongodb算是安装完毕。注意生产环境安装还需要为mongodb配置访问权限,此处不详细讨论了。
下载xhgui
git clone https://github.com/perftools/xhgui
代码下载完以后上传到网站目录,具体操作因环境而异,若不熟悉请先熟悉lnmp架构。上传完后执行
php /wwwroot/install.php
配置Nginx
假设我们需要调试的网站位于dev.fqdn而xhgui位于xhgui.fqdn
则需要在dev.fqdn配置文件的location段加入
fastcgi_param PHP_VALUE "auto_prepend_file=/wwwroot of xhfui.fqdn/xhgui/external/header.php";
此配置的作用是在dev.fqdn下的每个php经过fastcgi的时候自动在开头加入这个xhgui/external/header.php而这个文件的作用是运行你的代码前调用tideways开启调试你的代码运行完毕后结束调试并把结果传入mongodb等待查看。
xhgui.fqdn配置则是正常php网站的配置,不赘述了。注意需有这一行
location / { try_files $uri $uri/ /index.php?$args; }
配置tideways
tideways的配置文件位于/config/config.php安装时这个文件不存在,故需要把默认配置复制到这个文件
cp <wwwroot>/config/config.default.php <wwwroot>/config/config.php
除了mongodb链接配置(一般无需调整)主要关注这一个回调函数
// In config/config.php return array( // Other config 'profiler.enable' => function() { return rand(1, 100) === 42; } );
-
默认配置的此函数仅仅做了节流,截取1%的流量进行分析。这是基于生产环境的性能考虑,如果我们仅仅是在开发环境中使用,就不需要管这么多了。例如
// In config/config.php return array( // Other config 'profiler.enable' => function() { return true; } );
-
这个配置就会把所有流量全部截取分析。令人哭笑不得的是,这所有流量包括了xhgui.fqdn的流量,这显然不是我们想要分析的。还有的时候我们也不想看到dev.fqdn中管理界面的流量,这就需要一些进阶配置了。例如
'profiler.enable' => function() { $url = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']; if (strpos($url, 'dev.fqdn/admin') === 0) { return false; } elseif (strpos($url, 'dev.kucloud.win') === 0) { return true; } return false; },
-
这样一来就只会看到我们希望分析的请求了。
参考:
phperzh