性能测试监控建模之记录Tomcat性能调优

本文正在参与 “性能优化实战记录”话题征文活动

前言

说起性能测试就来劲了,因为它作为测试领域为数不多需要深厚技术功底的技能之一;

但是,入门容易,深耕难。想要在这一门技术里修炼成大咖,没有个5-6年技术积累是很难达到的;

关键在于性能问题的发生是无规律的,却又有一定的套路在里面,需要不断学习和总结经验。

这里我也建议:学习不一定要拿自己公司的项目,而是先去拿别人开源的项目来练手,自己设定性能问题,然后通过现象了解性能问题的本质,以达到性能优化的目的。

环境准备

这里不只是环境搭建,而且包括脚本开发、数据构造、监控平台等等一切为执行性能测试场景而准备

  • 推荐前面搭建的Jforum系统,脚本也是前面开发完成好的,只需要按照场景执行观察并分析结果就行
浏览帖子的场景
  • 运行场景:设置30个线程,没有思考时间,持续5分钟。。。
  • 场景现象:一段时间后tps急剧下降、服务无响应、日志报错、无慢sql;服务器 cpu 100%、平均负载飙高回落、内存正常
  • 分析日志:%TOMCAT_HOMT%/logs/catalina.out
"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007fd5f811d800 nid=0xc94 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fd5f811b000 nid=0xc93 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fd5f810c800 nid=0xc92 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fd5f80dc000 nid=0xc90 in Object.wait() [0x00007fd5e8bfa000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
	- locked <0x00000000f81c9a98> (a java.lang.ref.Reference$Lock)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007fd5f811d800 nid=0xc94 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007fd5f811b000 nid=0xc93 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007fd5f810c800 nid=0xc92 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007fd5f80dc000 nid=0xc90 in Object.wait() [0x00007fd5e8bfa000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
	- locked <0x00000000f81c9a98> (a java.lang.ref.Reference$Lock)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
复制代码
性能诊断

top命令监控cpu资源、抓出占用CPU过高的进程pid、jstack检索线程状态; 分析日志,出现了BLOCKED线程阻塞,造成的原因有:宽带、中间件线程池、数据库连接池等; 分析原因内网压测不大可能是带宽问题,可能是tomcat中间件线程池不够,线程池占满无法创建新连接,等待连接。

配置优化

先猜测是tomcat线程池不够,那就调整20为300

反复测试

性能测试是一个不断重复的过程,一直测试到发现不了问题为止。

  • 用一个场景运行,发现一段时间后tps急剧下降,再去分析服务日志:
Exception in thread "http-bio-8080-exec-28" Exception in thread "http-bio-8080-exec-27" java.lang.OutOfMemoryError: GC overhead limit exceeded
	at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57)
	at java.nio.ByteBuffer.allocate(ByteBuffer.java:335)
	at sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:251)
	at sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:231)
	at sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:69)
	at java.io.InputStreamReader.<init>(InputStreamReader.java:100)
	at freemarker.cache.FileTemplateLoader$4.run(FileTemplateLoader.java:210)
	at freemarker.cache.FileTemplateLoader$4.run(FileTemplateLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at net.jforum.util.legacy.clickstream.ClickstreamFilter.doFilter(ClickstreamFilter.java:59)
java.lang.OutOfMemoryError: GC overhead limit exceeded
复制代码

看到OutOfMemoryError错误就豁然开朗了,先肯定前面的猜测对了,优化了服务配置

性能分析

OOM内存出现了问题,也就是GC堆内存开销超出限制,可能是程序在不断的GC但是缓慢,来不及给下一个线程使用;所以还是有可能是程序的内存分配问题,即使增加配置:-XX:-UseGCOverheadLimit,还是会抛出异常:java.lang.OutOfMemoryError: Java heap space,这样就可以解释为堆内存溢出了。

堆内存原因:需要调整tomcat的jvm参数增大堆内存Xms\Xmx

  • jvm参数优化

增加tomcat线程池、调整tomcat的jvm参数128m至1g

再次运行场景

  • 结果,不再出现异常情况,支持30个线程不断并发,tps上升后到达一个稳定过程,RT也没有增高,维持在3s以内。

猜你喜欢

转载自juejin.im/post/7018383773804789768
今日推荐