通过XHProf排查PHP代码的性能问题
昨天头儿反馈wiki系统不能用了,晚上我用请求日志里面比较慢的请求重试了下,请求起来都比较快;从zabbix监控和数据库的日志来看,问题时段也没有发现异常,暂时无法定位具体原因。
为了解决这个问题,我用XHProf性能分析插件,给程序加个更细致的日志,这样下次出现类似问题,应该就可以确定具体原因了。
XHProf已经好几年没用过了,昨晚用的过程中,发现遇到一些问题;为了便于今后再次用到XHProf时,能够快速搭建,这里记个笔记。
安装
直接去pecl网站下载即可,PHP5.2.0以上版本都支持(wiki系统所在的服务器很老了,PHP版本是5.2.13,真是幸运,要是版本再低,XHProf就不能用了)。
如果是PHP7,目前pecl没提供扩展,要去另外的地址下载源码编译,可以参考这篇文章。
后端扩展
编译安装和普通PHP扩展一样,进入源码包解压后的extension目录:
which phpize
which php-config
/usr/local/bin/phpize
./configure —with-php-config=/usr/local/bin/php-config
make
make install
然后在php.ini中添加扩展,并指定日志文件的存放路径:
extension=xhprof.so xhprof.output_dir=/tmp/xhprof
装好后,记得重启下PHP-FPM进程或者Aapche的httpd进程。
前端页面
将源码包解压后的xhprof_html和xhprof_lib,放入服务器的web目录下即可访问。
查看日志列表:
查看日期详情:
http://this.is.domain.com/xhprof_html/index.php?run=5b5958946bfc2&source=20180726131356436
安装graphviz
wget http://www.graphviz.org/pub/graphviz/stable/SOURCES/graphviz-2.30.1.tar.gz
tar zxf graphviz-2.24.0.tar.gzcd graphviz-2.24.0
./configure
make
make install
看以前的笔记,说是有时候make和make install中会报错,但是仍然能用。不过我自己编译的时候没遇到这个报错。
使用
为了让日志文件的名称能够自定义,我自己在默认的扩展方法之上,封装了两个方法:
function xhprof_start()
{
xhprof_enable();
}
function xhprof_stop($cost = 0)
{
$xhprof_data = xhprof_disable();
$xhprof_root = "/var/www/html";
include_once $xhprof_root."/xhprof_lib/utils/xhprof_lib.php";
include_once $xhprof_root."/xhprof_lib/utils/xhprof_runs.php";
$xhprof_runs = new XHprofRuns_Default();
$uri = preg_replace('/([\x80-\xff]*)/i','', urldecode($_SERVER['REQUEST_URI']));
$ts = date("YmdHis") . floor(microtime()*1000);
$uri = str_replace(array("/", "."), array("-", "-"), $uri);
$uri = trim($uri, "-");
// $key = $ts . "." . $cost . "." . $uri;
$key = $ts . "." . $cost;
$key = $ts;
$run_id = $xhprof_runs->save_run($xhprof_data, $key);
}
生成的日志文件名类似这样:5b5958946bfc2.20180726131356436.xhprof
注意,第一个点号之后的内容是source,可以理解为日志文件的一个分类,这个字符串里面不要包含横杠,否则通过页面查看详情时,无法正确识别到。
日志文件名格式为:
唯一Hash码.source.xhprof
只能有2个点号。
排查慢请求
cat /usr/local/apache2/logs/2018_07_25_access_log|awk '{print $4"\t"$11"\t"$7}'|sort -nk2
通过图形界面查看日志信息
我遇到一个报错:
failed to execute cmd: ” dot -Tpng”. stderr: `Error: Could not find/open font Error: Could not find/open font
报错位置是:utils/callgraph_utils.php:121
是执行dot -Tpng命令时报出的错误,从报错来看,是找不到某个字体文件。但是因为没有报出具体是哪个字体 文件,所以不好排查,我就直接将windows下所有的字体文件都拷贝到Linux上了。
Linux字体文件目录(记得先做个备份):
/usr/share/fonts/chinese/TrueType
Windows字体文件目录(有590M左右):
C:\Windows\Fonts
拷贝上去后,发现还是不行的。
换了个服务器、将graphviz改为yum安装,还是不行。
由于目前其他紧急的事情较多,先暂时通过表格查看结果,就不看图形了。后续有时间再排查下。