上一篇:【swoole4.0】一次qps提升之旅(一) 我们介绍了如何使用tideways_xhprof,这一篇将介绍 当拿到性能分析数据后,如何看,以怎么看
先看结果
压测脚本:
优化前的压测数据:
优化后的压测数据:
效果非常明显,那是怎么做到的呢?
数据可视化
所有的秘密其实tideways_xhprof都已经帮我们分析出来了,文件就在:
如之前所说,直接打开这个文件,是一串序列化的文本数据,无从看起,所以我们需要借助一个可视化工具, 安装步骤如下:
1、git clone https://github.com/phacility/xhprof 到你本地
2、配置nginx , fpm , root目录指向 xhprof_html
我本地的配置如下,供大家参数:
然后,hosts文件增加一条:
127.0.0.1 xhprof.com
这样,浏览器 http://xhprof.com 就可以直接访问了
但由于xhprof年久失修,所以在php7环境下跑不通,所以需要修改以下几个地方:
index.php文件
增加:
//指定分析文件目录
$dir = "/tmp/xhprof";
$xhprof_runs_impl = new XHProfRuns_Default();
修改为:
$xhprof_runs_impl = new XHProfRuns_Default($dir);
xhprof_lib/utils/xhprof_lib.php文件注释掉:
//xhprof_error("Error in Raw Data: parent & child are both: $parent");
//return;
xhprof_lib/utils/xhprof_runs.php 文件
最开始增加一个function:
function difffilemtime($a, $b) {
return filemtime($b) - filemtime($a);
}
usort($files, create_function('$a,$b', 'return filemtime($b) - filemtime($a);'));
改为:
usort($files, 'difffilemtime');
查看庐山真面目
终于可以一看真面目了,我们看下优化前这个接口到底做了些什么?
这里分为上下二部分,上面的部分:
这个可以看个概览,大约知道整体的情况, 这一部分我们分析不了什么
下面的部分才是明细:
怎么看呢?先说一下表头的含义:
-
funciton name : 函数名
-
calls: 调用次数
-
Incl. Wall Time (microsec): 函数运行时间(包括子函数)
-
IWall%:函数运行时间(包括子函数)占比
-
Excl. Wall Time(microsec):函数本身运行时间(不包括子函数)
-
EWall%:函数本身运行时间占比(不包括子函数)
-
Incl. CPU(microsec):函数CPU占用时间(包括子函数)
-
ICpu%:函数CPU占用时间占比(包括子函数)
-
Excl. CPU(microsec):函数本身CPU占用时间(不包括子函数)
-
ECPU%:函数本身CPU占用时间占比(不包括子函数)
-
Incl. MemUse(bytes):函数使用内存(包括子函数)
-
IMemUse%:函数使用内存占比(包括子函数)
-
Excl. MemUse(bytes):函数本身使用内存(不包括子函数)
-
EMemUse%:函数本身使用内存占比(不包括子函数)
嗯,好晕啊,这么多定义,到底看哪个啊?
总时间和CPU时间
总时间 = cpu时间 + i/o时间
i/o时间:
大部分是网络i/o,如和mysql, redis交互等,这个时间程序本身控制不了,而且一但程序走到i/o部分了,理论上cpu已经让出来了
cpu时间:
这个才是决定我们单机性能的关键, 极致的利用率就是cpu100%了,不过可能机器也暴了~~,但减少cpu时间,就可以让一个cpu在单位时间里处理更多的请求,所以要我们找出哪里消耗了我们的CPU
怎么找?
明确里默认是按 Incl. Wall Time 排序,所以我们要按Excl.CPU来排序(点击表头的Excl. CPU(microsec) 即可), 排完之后,结果如下:
聪明的你,应该立马发现了一个大问题,写个debug日志,居然占用了 17.4%的CPU时间,于是有了第一次优化:
第一次优化
第一次优化成本非常小,只是把日志级别调低了,来看一下压测结果:
对之优化前的2666,性能差不多提升了17~18%,和这里的分析占比几乎差不多
再来看一下去掉之后的情况:
还是个写日志的,这个日志其实也可以去掉,或者可以优化,只记录慢日志,我再降低一下日志级别,看看结果如何?
再次提升10%,符合预期。
同志们!!,写日志还是很昂贵的。
第二次优化
几乎没有成本的优化,性能就提升了如此之多,是不是有点不敢相信,事实上大部分问题的解决方案就很简单,只是我们不知道而已,接下来我们继续看,还有哪些可以优化的点, 还是把结果拉出来溜溜:
看到了,排第一的是mysql:query,这个是swoole mysql内置的方法,动不了,接下来一堆,都是跟FastRoute相关的,这几个加起来总共占用了近20%的cpu时间了,这里有个小技巧,我们点击 FastRoute\RouteParser\Std::parse 进去看一看有啥?
也是非常直观,可以看到这个funcion的父方法和子方法,可以看出prase方法(包含子方法),cpu占用16%
但这是一个引入的第三方包,怎么优化呢?这个就不像日志优化那么简单了,需要看一下具体的实现逻辑:
路由的配置如下:
这里面的关键逻辑是 FastRoute需要读取配置,进行正则相关的匹配,然后解析出结果,经过一番长达1分钟的思考,优化方案出来了,增加一个静态路由的能力,直接解析, 关键代码如下:
配置增加一项:
总共花了不到3分钟写代码,保存,再一压,看到的就是开头的结果:
所以通过xhprof,我们可以很方便的针对现有的代码做相对合理的优化
(PS: 这里的压测结果比上次要好,原因应该是上次本地开了一堆的程序,消耗了一部分资源)
再来看一下分析结果:
可以看到FastRoute相关的调用已经消失了,如果想继续优化,那应该就是EasySwoole\Http这个库了,不过目前的QPS已经远远超出预期,所以决定优化到此为止
最后希望这次优化之旅能给大家带来帮助,第二次优化的代码在:
https://github.com/shenzhe/FamilyFrameWork/blob/master/src/Core/Route.php, 查看原文可达
----------伟大的分割线-----------
PHP饭米粒(phpfamily) 由一群靠谱的人建立,愿为PHPer带来一些值得细细品味的精神食粮!
饭米粒只发原创或授权发表的文章,不转载网上的文章
所发的文章,均可找到原作者进行沟通。
也希望各位多多打赏(算作稿费给文章作者),更希望大家多多投搞。
投稿请联系:
本文由 桶哥 授权 饭米粒 发布,转载请注明本来源信息和以下的二维码(长按可识别二维码关注)
文章评论