【swoole4.0】一次qps提升之旅(二)

2019年4月12日 264点热度 0人点赞 0条评论

上一篇:【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带来一些值得细细品味的精神食粮!


饭米粒只发原创或授权发表的文章,不转载网上的文章


所发的文章,均可找到原作者进行沟通。


也希望各位多多打赏(算作稿费给文章作者),更希望大家多多投搞。


投稿请联系:


[email protected]


本文由 桶哥 授权 饭米粒 发布,转载请注明本来源信息和以下的二维码(长按可识别二维码关注)

图片

35890【swoole4.0】一次qps提升之旅(二)

这个人很懒,什么都没留下

文章评论