京东质量社区 记一次 618 演练压测 TPS 上不去排查及优化 | 京东云技术团队

京东云开发者 · 2023年06月05日 · 最后由 link@2023 回复于 2023年10月10日 · 7980 次阅读

本文内容主要介绍,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 的值也下去了。达到了预期的一个目标。

总结

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

作者:京东健康 牛金亮

来源:京东云开发者社区

共收到 11 条回复 时间 点赞

naive。

大厂不是都应该全链路监控了吗,日志都搜索,出错直接都可以查询了的吗,包括这些 GC 的日志,不是都应该图标化了吗?咋还是命令行,自己手工查日志,这和出来讲东西的有点出入呀。

fgc 不会占用 cpu 吗?

没记错的话,1GB 是默认值

优化的话,不应该是改 sh 启动脚本么... 可以根据机器配置,自定义 JVM 堆内存,这应该都是基操了。

以后这些是不是都是 AI 来排查了。。。

6楼 已删除

大佬有两个问题期待答疑一下:

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

不用太关注操作系统层面的资源不足的问题了?我看其他人分享的好多会因为这块的问题导致性能的瓶颈。

2.接下来从代码层面和 JVM 层面进行排查,可能是项目代码中出现了线程阻塞,导致线程出现等待,响应时间变长,请求不能及时打到被测服务器上。

通过什么来推测的,直接就来看 jvm 这些呢,个人感觉至少要从一些指标看起来有点异常往这边排查的吧。很多服务,看代码是不是有点粗鲁了😂

lazyBoy 回复

案例里的是设置过的了,只是设置过小
默认的配置,最大是按物理内存的 1/4,最小是物理内存的 1/64

东少 回复

emmm,看了下官网,咱说的都不对。
关于堆内存的默认配置,32/64 位会有点区别,客户端/服务端也会有区别。 但都会有个上限,不完全按比例。

但你说之前是手动设置的 1GB,我还是不大理解的.... 机器内存不会只有 2G 吧... 一般配置物理内存的 1/2~2/3 作为 Xmx

迷龙 回复

1 问题:系统层面的 cpu、内存大小、网络带宽,主要是硬件的资源不用太关注了,主要指的是被压机器的 cpu 的配置调优、内存的调优、带宽的速度这些都已经是配置好了。
在压测的时候,需要看下被压机器的 cpu、内存、IO 指标,如文章写了,压测时被压 cpu 是 10%,被压机器的 cpu 是正常的,同时也要监控 tps、tp99 等指标,这场景是 tps 不满足预期、tp99 偏高、cpu 正常。
2 问题:并不是直接来看 jvm 的,对于这场景是 tps 不满足预期、tp99 偏高、cpu 正常。对于这个现象首先排查可能会存在一些阻塞了,被压机器处理的流量不是预期的流量导致现象 tps 不高,cpu 也不高,从头开始排查首先网络带宽方面不是瓶颈,然后猜想是否打个线程 dump 文件排查哪里阻塞。
同时也排查这个接口的调用链路,调用了哪些服务,排查下游服务是否存在瓶颈,如文章所下排查到下游的领券接口(这个服务部署在另外的机器上)超时,并且 cpu 偏高,继而转到这个下游接口的场景 tp99 偏高,cpu 偏高的排查,可能会存在哪些原因。对于这个场景可能原因也会有很多,
对于这个接口超时首先想到了这个接口调了过滤器,猜测是不是这个原因,其实也可以看这个服务的日志。但是最后验证不是这个原因,又查看了 jvm 的日志,然后发现了根源。

明白了,多谢解答


这些截图我都看不到

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册