本文内容主要介绍,618 医药供应链质量组一次演练压测发现的问题及排查优化过程。旨在给大家借鉴参考。

背景

本次演练压测背景是,2B 业务线及多个业务侧共同和 B 中台联合演练。

现象

当压测商品卡片接口的时候,cpu 达到 10%,TPS 只有 240 不满足预期指标,但是 TP99 已经达到了 1422ms。

排查

对于这种 TPS 不满足预期目标,但是 TP99 又超高,其实它的原因有很多中可能,通过之前写过的文章对性能瓶颈的一个分析方式《性能测试监控指标及分析调优》,我们可以采用自下而上的策略去进行排查:

首先是操作系统层面的 CPU、内存、网络带宽等,对于集团内部的压测,机器的配置、网络带宽,这些因素运维人员已经配置到最优的程度了,无需我们再关心是否是因为硬件资源系统层面导致的因素。

接下来从代码层面和 JVM 层面进行排查,可能是项目代码中出现了线程阻塞,导致线程出现等待,响应时间变长,请求不能及时打到被测服务器上。对于这种猜测,我们可以在压测过程中打线程 dump 文件,从 dump 文件中找到哪个线程一致处于等待状态,从而找到对应的代码,查看是否可以进行优化。这块同开发一同分析整个接口的调用链路,商品卡片接口调用运营端的优惠券的可领可用接口,通过查看此接口的 ump 监控那个,发现调用量其实并不高。接下来通过查看运营端机器的日志发现,调用可领可用优惠券接口已经超时了,并且机器 CPU 已经偏高,使用率平均在 80% 以上。是什么原因导致调用可领可用接口大量超时,成为了问题的关键点。

image.png

首先我们代码层面分析,这个可领可用优惠券接口还会调用一个过滤器进行过滤,于是猜测是不是这个过滤器接口把 CPU 打满了,但是通过监控过滤器接口的 ump 中可以看到它的 TP99 并不是很高,说明它的调用量没有上去,这种猜测可能不成立。还好当时代码这设置了一个开关是否使用过滤器,我们把过滤器的开关关闭后。再次进行压测商品卡片接口,发现还是没有解决问题,TPS 仍然不高,并且 TP99 还是很高。说明这个猜测真是不成立的。

接下来我们转换思路,查看 JVM 日志,是否从中寻找到一些蛛丝马迹,果然从 JVM 的 GC 日志中可看到 Ygc 和 Fgc 的时间占用比较长,其中 Fullgc 的时间占用时间达到了 7165ms,并且从中可以查看 jvm 的参数配置,发现 Xms 和 Xmx 配置的值都是 1024,只有 1 个 G。问题的原因找到了,这台被压测的机器 JVM 参数配置的 Xms 和 Xmx 值太小了,如果-Xmx 指定偏小,应用可能会导致 java.lang.OutOfMemory 错误

image.png

image.png

对于 JVM 的介绍这部分比较庞大涉及到类加载方式、JVM 内存模型、垃圾回收算法、垃圾收集器类型、GC 日志,在这就不做详细说明了,想要了解详细内容可以看看《深入理解 JAVA 虚拟机》这本书。

此处简单说明下什么是 Ygc 和 Fgc,以及 Xms、Xmx 的含义。

JVM 内存模型中,分为新生代、老年代和元空间,新生代又分为 eden 区、Survivor0、Survivor1 区。对象优先在 Eden 区分配,当 Eden 区没有足够空间时会进行一次 Minor GC,执行完第一次 MGC 之后,存活的对象会被移动到 Survivor(from)分区,当 Survivor 区存储满了之后会进行一次 Ygc,但是 Ygc 一般不会影响应用。当老年代内存不足的时候,会进行一次 Full GC,也就是 Stop the world,系统将停止运行,清理整个内存堆(包括新生代和老年代),FullGC 频率过大和时间过长,会严重影响系统的运行。

Xms,JVM 初始分配的堆内存

Xmx,JVM 最大分配的堆内存

一般情况这两个参数配置的值是相等的,以避免在每次 GC 后堆内存重新进行分配。

优化

最后修改机器的 JVM 数配置

查看 JVM 配置参数

重启后再次进行压测,我们的 TPS 指标上来了,并且 TP99 的值也下去了。达到了预期的一个目标。

总结

其实对于一个性能瓶颈问题的分析排查定位,犹如医生看病,需要望闻问切,通过表面现象逐层的去排除一种种的可能性,最终找到其根本原因,对症下药解决问题。本文介绍的也只是性能瓶颈问题中的一个小小的部分,其实在压测过程中还会遇到各种各样的问题,但是我们掌握了方法论,其实都可以按照相同的思路去排查,最终找到根源。

作者:京东健康 牛金亮

来源:京东云开发者社区


↙↙↙阅读原文可查看相关链接,并与作者交流