天师府_一次有趣的 JVM 性能调优

4. 一次有趣的 JVM 性能调优

4.1 问题描述

  • 服务qps 2000左右,性能稳定。但每天都会偶尔出现几次查询Db超时

    • 超时机制:客户端使用并发异步查询,设置超时时间为200ms

      ByteBuffer byteBuffer = completionStage.toCompletableFuture().get(getTimeout, TimeUnit.MILLISECONDS);
      

4.2 问题定位

  1. 怀疑Db服务端响应慢,分析过程如下

    • 监控:Db服务端没有超过200ms的查询 —— 排除服务端慢查询的case

      • 分析:服务端没有慢查询,客户端有超时,会不会是因为网络问题(网络IO)
    • 监控:网络IO持续问题 —— 因为超时是偶先,网络IO很稳定的情况下不太可能是此原因

      • 问题定位到客户端和应用本身
  2. 怀疑Db客户端有问题,分析过程如下

    • 场景描述:qps较高,Db客户端采用异步执行
    • Db客户端异步原理简述:客户端会为每个服务端节点的每个CPU线程创建一个连接
      • 怀疑点:查询db任务较多,任务进入客户端线程池的队列中,等待执行时间超过200ms,导致超时
        • 分析:现在每个客户端会建立192个连接,且服务端处理单次任务大概在毫秒级别,所以基本不太可能是这个原因
      • 连接如图
        在这里插入图片描述
  3. 查看服务本身各项监控指标(此时基本快没有头绪了!!)

    • 服务的网络、cpu、磁盘、内存一切都很恒定

    • 内存:Minnor GC正常,基本未产生Full GC

      • 单独列内存监控截图,是因为一般服务性能下降,是因为内存泄漏导致Full GC、内存溢出等原因

在这里插入图片描述

  1. 可以看到内存在38%左右就降下来,38%是因为配置的Minnor的大小占内存30%

    • 此处可以看到,虽然Minnor GC基本不影响性能,但是明细可以感觉到gc的频率很高
    • 开始怀疑是否由于频繁的Minnor GC导致
  2. 查看服务GC具体情况;得出结论如下:

    • 优化前:Minnor GC频率基本20分钟一次,超过100ms的gc频现(年轻代大小3G)
      在这里插入图片描述

    • 优化前:Minnor GC平均GC耗时:85ms

    • 在这里插入图片描述

  3. 查看jvm参数配置发现:年轻代使用UseParNewGC收集器,老年代使用CMS(具体不描述)

    • UseParNewGC:并发串行收集器,它是工作在新生代的垃圾收集器,它只是将串行收集器多线程化,除了这个并没有太多创新之处,而且它们共用了相当多的代码。它与串行收集器一样,也是独占式收集器,在收集过程中,应用程序会全部暂停。但它却是许多运行在Server模式下的虚拟机中首选的新生代收集器,其中有一个与性能无关但很重要的原因是,除了Serial收集器外,目前只有它能与CMS收集器配合工作
  4. 此处怀疑点

    1. Minnor GC超过100ms(甚至300ms)的case,肯定会早成200ms超时限制
  5. 开始优化jvm参数(使用jdk 1.8默认收集器)

    1. 使用UseParallelGC收集器
      1. UseParallelGC:并行收集器,同时运行在多个cpu之间,物理上的并行收集器,跟上面的收集器一样也是独占式的,但是它最大化的提高程序吞吐量,同时缩短程序停顿时间,另外它不能与CMS收集器配合工作。
    2. 调整参数,设置最长gc耗时80ms,启动AdaptiveSizePolicy
      1. AdaptiveSizePolicy,会根据GC的情况自动计算计算 Eden、From 和 To 区的大小;
    3. 注意事项:
      1. 在 JDK 1.8 中,如果使用 CMS,无论 UseAdaptiveSizePolicy 如何设置,都会将 UseAdaptiveSizePolicy 设置为 false;不过不同版本的JDK存在差异;
      2. UseAdaptiveSizePolicy不要和SurvivorRatio参数显示设置搭配使用,一起使用会导致参数失效;
      3. 由于AdaptiveSizePolicy会动态调整 Eden、Survivor 的大小,有些情况存在Survivor 被自动调为很小,比如十几MB甚至几MB的可能,这个时候YGC回收掉 Eden区后,还存活的对象进入Survivor 装不下,就会直接晋升到老年代,导致老年代占用空间逐渐增加,从而触发FULL GC,如果一次FULL GC的耗时很长(比如到达几百毫秒),那么在要求高响应的系统就是不可取的。
  6. 调优后效果

    1. Minnor GC频率10分钟一次(年轻代大小2G)

    2. 平均GC耗时:25ms(优化前85ms)
      在这里插入图片描述

    3. 最大GC耗时:30ms(优化前由300ms的case)

  7. 超时结果对比(武汉机房为jvm调优后,北京机房为调优前)

    1. 武汉与北京机房超时次数比例(三天数据):1:20
  8. 仍会出现超时情况,最终打算如下优化:

    1. 所有机房使用调优后的jvm参数,更换gc收集器
    2. 需要明白:200ms超时在高qps等情况下,难免会因为各种服务或网络问题偶现,不能完全避难
    3. 经验:我们之前是保持9999在1s内,999在800ms内(直接面对端上)
    4. 现状:我们期望的耗时 < 200ms
      1. 假设9999的标准是200ms,按照2000的qps计算,1秒内>0.2次超时即预警,5秒内>1次超时及预警
      2. 假设999的标准是200ms,按照2000的qps计算,1秒内>2次超时即预警
      3. 目前设置10分钟大于1次即预警,标准过高,预警意义不是很大
    5. 调整:venus小预警时间维度1分钟
      1. 1分钟内超时 > 1次超时(会打印2 次error)。(目前超时一次会打印两条error,待优化)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值