一千零一个优化-0001-记一次接口性能的“边缘”优化

背刺来袭

“S市的小伙伴们普遍反应测试平台贼不好用,都快要放弃另起炉灶了!” S市的业务测试负责人给上了重重的一记背刺。小树懵在原地,脑袋都是嗡嗡的,脸上也烧了起来。相比之前的反馈,这次生猛了许多。当然理智的小树这时候会开始沉思了,到底是哪里做的不好。背后的问题其中一项是有一个接口请求超过13秒,而且这个接口在使用的主流程中还特别频繁。那这个问题究竟是怎么来的呢,那我们就得从小树刚进入公司H市分部开始说了…

背刺的由来

小树一进入公司,就迅速的搭起了一个基于metersphere的开源测试平台。也顺利推广了开来,开始安然无事,最多就是会有些不知道组件怎么使用的问题,平平安安的度过了3个月。3个月后,小树也正常开始展开做其他相关的平台维护和开发工作,期间偶尔会有些声音抱怨平台有的时候会比较慢,也不知道是开玩笑还是真有问题,一般大家都是笑笑就过了。小树确认过后,没能重现也就不了了之了。

时间转眼又过了2个月,S市的小伙伴反映卡顿的频次逐步升高,这不禁让男主怀疑起来是否有什么问题,于是和H市的同事了解情况,可H市的同学表示快确实不能说是快,但也还能接受。随后S市断断续续的再反馈着,但是也不是特别急迫,于是又带着问题过了2月,从平台初建到现在,小树发现,2地的同事的自动化脚本水平越来越好,从最初的写个单接口写个校验,到最近的模块化,规模化变化都是非常惊人的。脚本的数量级和脚本的复杂程度也不可同日而语。特别是S市的脚本有着翻天覆地的变化,单个脚本的能力都是多样且强大。

话说回来,就在这个时候,H市也陆续有同学开始反馈该接口的响应体感上的不能接受。这个时候小树才正式介入,定位接口,然后通过前端缓存接口内容,减少调用次数,从而减缓延迟带来的体感不适。原以为故事到这里就结束,又恢复天下太平了。

事与愿违,就在又过去2个月后的今天,小树懵在了原地,问题并没有解决,而且S市同学已经不想再忍了,最后捅到了主管那里。其实小树并不会因为主管的压力感到伤感,只是会对反馈感到内疚不安。于是就又开始了重新和问题斗智斗勇。

提刀上马

经过了之前一次调优的经验,小树很快便找到了问题接口的代码,又重新读了一遍,这次明显比之前更快。这里的循环做的恐怕有性能问题,递归加数据库(io)查询,想不慢也难,小树灵机一动,心想:这个平台是个开源平台,想必其他人也有这个问题,很可能已经被开源组织优化了吧。抱着试一试的心态,小树提刀上马找起了开源代码上是否有更新记录。功夫不负有心人,问题块的代码确实被优化过了。

同步了最新代码,本地起了服务并开启了调用链路跟踪监控请求的时间开销。

image.png

不难看出,整个接口请求时间开销只用不到240毫秒,这可比线上的13秒快了不知道多少倍。于是开开心心的结案了,坐等应用发布。问题应该就此解决了,小树开开心心的去做其他工作了。

不出意外,就要出意外了

终于到了发布窗口,发布完后,小树直接找来几个S市同学写的自动化脚本,直接尝试了下这个慢接口对应的功能。性能有提升却不大,从原来的13秒左右降低到了10秒左右。整体功能体验上还是不能接受,太糟糕了。小树感觉到十分无力,迷茫。心说:怎么可能呢,明明我本地秒级的东西到了线上要十秒级。数据库本地连接比服务器连接更慢,要说有变化也应该是服务器上更快才对。

于是用arthas在云服务器上也追踪了下方法的调用时长。整体数据表现和本地表现差不多,甚至确实更快一点。只要130毫秒左右。

小树不解之余,一次次的trace ,折腾了好一阵子,最后发现即使是整个接口方法也只需要不到200毫秒。整个arthas的排查过程花了不到十分钟,却让小树如度春秋,更是雪上加霜,更加没有头绪没有章法。

再战

小树原先盯着Chrome浏览器的开发者模式窗口接口时长上写的9.3秒的眼睛,也慢慢的失去了光泽。 突然间眼里泛起了微光。这里有点点奇怪啊,小树心里萌生了一些东西。因为小树的鼠标焦点移到了瀑布图上的时候,小树发现:

image.png

这里有一个点很奇怪,为什么请求的发送时间比请求处理时间还长这么多? 这个是怎么回事。于是小树查看了下请求数据。瞬间被吓到了,一个请求体居然有6.3MB,这个接口返回只有不到250B,完全是2个数量级。

image.png
然后再联系小树公司使用的都是国外的云服务器,单纯ping云服务都有200多毫秒延迟,小树便大胆猜想了一下,如果网络比较差的环境下,那6.3MB的传输花费远比服务处理时间更久。之所以本地调试的时候无感知,因为本地前后端的传输速度可以忽略不计,因此本地不能重现线上的问题。

小树通过前后端gzip加压解压的方式进行了优化,由客户端和服务端进行数据的展开,减少网络上的消耗,顺便在紧急发布窗口重新发布了测试平台。

//  前端压缩请求体,公共方法
export function zipString(content) {
  return btoa(pako.gzip(content, {to: 'string'}));
}
// 后端解压请求体,公共方法
public static String ungzip(String content) {
    byte[] bytes = Base64.getDecoder().decode(content);
    try (ByteArrayOutputStream out = new ByteArrayOutputStream();) {
        IOUtils.copy(new GZIPInputStream(new ByteArrayInputStream(bytes)), out);
        return out.toString();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

image.png

请求整体时间从原先的13秒直接压缩到秒级。发布以后问题终于得到了解决,小树心中的大石头终于放下了。等待第二天的到来,好找S市的同学求证最终效果。

小树的总结

为什么这些问题之前没有发生,小树最后整理了下信息,其实自动化平台已经逐步深入人心,同学们的思路也慢慢被打开,使用的方式方法也会越来深入,所以请求内容也就越来越大,小脚本的情况下,这个请求内容也不会有这么大。只能说小树的新目标又有了,为了适配小树的公司环境,小树需要做更多的改造让测试平台能适配发展中的公司了。

有了这次的经验,小树对待技术,又多了一些感悟,在这次问题的解决中,其实问题相对还是比较简单,很快便被定位和解决了。看问题还是得要从头到尾推敲一下,因为无论是开发的工具也好,方法也罢,都是一点点积累起来的,难保某一个小分支小细节不会犯错,所以看待问题的时候还是得有全局视野,去找寻这些问题和方向。

随后小树便开开心心的在晚上12点的钟声敲响前5分钟,关掉了电脑,钻进了被窝.不久就进入了梦乡。

…然后…在某个阴暗的角落,有一个bug正在静静地注视着小树…


欢迎关注微信公众号:树叶小记,发现更多精彩

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYeQZVV3' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片