压力测试 JMeter 性能监控 jvisualvm 性能调优

Posted 澄清石灰水t

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了压力测试 JMeter 性能监控 jvisualvm 性能调优相关的知识,希望对你有一定的参考价值。

1、压力测试

1.1 基本概念

      压力测试考察当前软硬件环境下系统(项目)所能承受的最大负荷并帮助找出系统瓶颈所在。压测都 是为了系统(项目)在线上的处理能力和稳定性维持在一个标准范围内,做到心中有数。

      使用压力测试,我们有希望找到很多种用其他测试方法更难发现的错误。有两种错误类型是: 内存泄漏并发与同步

    有效的压力测试系统将应用以下这些关键条件:重复,并发,量级,随机变化

1.2 性能指标

(1)响应时间(Response Time: RT)

       响应时间指用户从客户端发起一个请求开始,到客户端接收到从服务器端返回的响应结束,整个过程所耗费的时间。

(2)最大响应时间(Max Response Time)

    指用户发出请求或者指令到系统做出反应(响应)的最大时间。

(3)最少响应时间(Mininum ResponseTime)

    指用户发出请求或者指令到系统做出反应(响应)的最少时间。

(4)90%响应时间(90% Response Time)

是指所有用户的响应时间进行排序,第 90%的响 应时间。

(5)HPS(Hits Per Second)

    每秒点击次数,单位是次/秒。

(6)TPS(Transaction per Second) 吞吐量

    系统每秒处理交易数,单位是笔/秒。

 根据经验,一般情况下:

金融行业:1000TPS~50000TPS,不包括互联网化的活动

保险行业:100TPS~100000TPS,不包括互联网化的活动

制造行业:10TPS~5000TPS

互联网电子商务:10000TPS~1000000TPS

互联网中型网站:1000TPS~50000TPS

互联网小型网站:500TPS~10000TPS

(7)QPS(Query per Second)

系统每秒处理查询次数,单位是次/秒。

小结:TPS、QPS、HPS

    对于互联网业务中,如果某些业务有且仅有一个请求连接,那么 TPS=QPS=HPS,一 般情况下用 TPS 来衡量整个业务流程,用 QPS 来衡量接口查询次数,用 HPS 来表示对服务器单击请求。

    无论 TPS、QPS、HPS,此指标是衡量系统处理能力非常重要的指标,越大越好

总结:

    从外部看,性能测试主要关注如下三个指标

吞吐量:每秒钟系统能够处理的请求数、任务数。

响应时间:服务处理一个请求或一个任务的耗时。

错误率:一批请求中结果出错的请求所占比例。

2、压力测试工具—JMeter

     Apache JMeter是Apache组织开发的基于Java的压力测试工具。能够对HTTP和FTP服务器进行压力和性能测试, 也可以对任何数据库进行同样的测试(通过JDBC)。

2.1 JMeter安装

Apache JMeter - Download Apache JMeter

直接官网下载下来解压后,进入bin/jmeter.bat 即可运行

 2.2 JMeter使用介绍 及 案例

2.2.1 使用介绍

(1)添加线程组

(2)选择测试HTTP请求(一般web项目,就是测这个)

(3)添加监听器

具体监听内容很难用语言描述,具体去2.2.2(3)去看测试结果

  2.2.2 示例—测试百度

(1)按照前面的教程配置好 线程组HTTP请求 

(2)配置好线程组HTTP请求以后,点击启动,便可开始测试

(3)查看测试结果

(3.1)查看结果树

结果树中,很容易看到各个HTTP请求的异常报告,便于快速找到异常原因

(3.2)查看汇总报告

     汇总报告,可以直观看到 吞吐量,异常数(可去结果树找异常原因) 等关键指标,快速评估系统性能好坏。

(3.3)聚合报告

聚合报告,主要是用于看90%,95% 百分位,进阶评估系统性能

(3.4)汇总图

通过图像更直观观察系统性能

(4)结论:

百度性能简直完美啊!

 2.2.3 测试自己写的接口(自然比百度性能差得多—后续会引申出调优

(1)改HTTP请求(线程组设置不用改,所有测试项目都可以用同样的设置)

(2)查看测试结果(各项指标都不好)

 (2.1)汇总报告

(2.2) 聚合报告

(3)结论

 吞吐量等各个性能指标都比百度差太多了。

(4)简单调优

通过IDEA增大虚拟机堆内存 Xms,调高以后,明显吞吐量提高

 2.4 一个windows系统引起的错误:JMeter Address Already in use

 2.4.1 错误现象

如果测试本机的某个服务并且设置的压力太大,就会发生JMeter Address Already in use 异常

比如:在线程组设置了10000个线程来压 127.0.0.1的10000端口

 随后出现JMeter Address Already in use异常

2.4.2 错误原因分析

      Jmeter模拟并发请求,会使用一个端口来建立连接,windows默认只给了5000个,并且4分钟回收一次,10000个线程打过来,一会就饱和了,就没端口可用,自然就会爆出JMeter Address Already in use异常

2.4.3 解决办法

    参考windows帮助文档https://docs.microsoft.com/zh-CN/troubleshoot/windows-client/networking/connect-tcp-greater-than-5000-error-wsaenobufs-10055

    因此解决办法就是增大临时端口,并且缩短回收时间

(1)增大临时端口

进入注册表,按照下图方式调整。一下子就多了几万个端口,给Jmeter临时用。

(2)缩短回收时间

还是通过注册表修改,默认4分钟回收一次端口,改成30s回收一次端口,自然这个效率大大提高

 3、性能监控

    就理解成windows中的任务管理器打开,然后监控cpu、内存,gpu,磁盘读写等性能参数

在普通web项目中(跟业务逻辑相关,跟图像无关的项目),最关注的就是cpu占用率,和IO性能(内存读写,和磁盘读写)

3.1 jdk自带性能监控工具—jvisualvm(用于监控自己写的代码性能)

    可监控本地和远程应用(远程应用需要配置,一般不用),主要用于监控内存泄露,跟踪垃圾回收,执行时内存、cpu 分析,线程分析

 运行:正在运行的

休眠:sleep

等待:wait

驻留:线程池里面的空闲线程

监视:阻塞的线程,正在等待锁

3.1.1 启动jvisualvm并添加功能插件

(1)启动

由于是jdk自带的,因此可以直接通过命令行启动

(2)安装加强插件Visual GC

点击工具—>插件

注意:有可能会遇到503错误,如果报错的话,是由于镜像地址出了问题,修改镜像地址的办法:

Step1:找到正确镜像链接:

打开网址:https://visualvm.github.io/pluginscenters.html

找到自己jdk版本对应的链接

 Step2:复制对应的链接

重新设置进jvisualvm

  修改好镜像后,再重新安装Visual GC 即可

3.1.2 示例—监控自己写的网关(cpu和IO)

 (1)Step1:用100个线程去压测自己写的网关

(2)通过jvisualvm 的 GC 可以直观看到CPU 以及 IO情况

可以看到也是费cpu,不怎么费内存

3.2 Docker性能测试工具(用于监控容器中的应用性能)

    由于springcloud项目,会使用很多第三方工具,比如nginxmysql,nacos,redis等等,这些第三方工具一般放在linux服务器的docker中,如何监控这些工具的性能(主要针对CPU和IO),就需要使用Docker自带的方法。

命令:docker stats

说明:如果对docker不够了解,可先快速学习docker:https://blog.csdn.net/chengqingshihuishui/article/details/119192809

3.1.1 演示:测试nginx性能

(1)首先:用压力测试软件JMETER,配置好100个线程,去压测nginx

监控nginx性能, 访问根路径即可

(2)查看nginx性能 

通过cmd,进入docker

然后 docker stats

  通过docker自带监控装置看到nginx某些指标,显然,nginx比较费cpu

3.3 监控应用

3.3.1 小案例引入

假设:已经完成了一个项目,项目架构如下:

  • 我们分别用JVM压测以下项目:

(1)直接压测Nginx

(2)直接压测GateWay

(3)直接压测某个简单微服务(比如就return一个 hello)

(4)直接压测首页index(首页会去微服务拿到数据后再渲染)

(5)压测调优后首页(开启thymeleaf 缓存)

(6)压测进一步调优后首页(开缓存,优化服务端数据库,降低打印日志级别)

(7)压测微服务三级分类获取

(8)压测微服务优化后三级分类获取(调优mysql)

(9)压测微服务进一步优化后三级分类获取(再加redis缓存)

(10)首页全量数据获取:包括各种静态资源(css,和图片)

(11)压测 Nginx+Gateway

(12)压测GateWay+简单服务

(13)压测全链路(nginx+gateway+微服务)

  • 压测结果如下:
压测内容压测线程数吞吐量/s90%响应时间99%响应时间
Nginx50233511944
Gateway5010367831
简单服务5011341817
首页一级菜单渲染50270(db,thymeleaf)267365
首页渲染(开缓存)50290251365
首页渲染(开缓存、 优化数据库、关日志、JVM内存优化)50700105183
三级分类数据获取502(db)/8(加索引)太久了太久了
三级分类(优化业务)50111571896
三级分类(使用redis作为缓存)50411153217
首页全量数据获取507(静态资源)
Nginx+Gateway50
Gateway+简单服务50312630125
全链路(nginx+gateway+微服务)5080088310

3.3.2 结论与优化方向(重点)

(1)中间件越多,性能损失越大,大多损失在网络交互了

     直接压测微服务效率最高,但是加入nginx,GateWay以后效率大大降低

(2)数据库优化的越好,性能越好。尽量一次查询好需要的数据,避免多次查询。

优化方向:一次从数据库查询所有有用数据,避免多次查询数据库,同时,数据库频繁查询字段加索引

(3)和数据库交互越少,性能越好

    如果每次都要从数据库去取数据,就算数据库优化到极致,也会损失很多性能,想不去数据库取数据,就得把这些数据放入缓存,下次模板直接从缓存中取数据

优化方向:加缓存挡在数据库前面,对于用户请求的数据,先从缓存中找,缓存没有再查数据库。如何使用缓存,请查看本链接

(4)首页渲染情况

    jvisualvm监控到伊甸园区内存频繁gc,把伊甸园区内存调大,效率明显提高

优化方向:JVM内存调优(后文就会讲)

(5)如果不访问首页的静态资源(图片、css等),性能越好

  首页的静态资源,如果也要通过请求微服务来获取,速度就太慢了。因此可以将静态资源放入nginx,静态资源直接从nginx访问,去掉中间环节。可以大大提高性能。

优化方向Nginx动静分离(本链接文章Nginx的第9章)

4、JVM调优内存调优

JVM调优应该很复杂,这里的JVM调优,只是简单的JVM内存调优

4.1 jvm内存模型

黄色部分是每个线程自己独立拥有的。

蓝色部分是线程共享的。

  • 本案例涉及的内存调优,主要是在堆Heap上干活,因此本文重点讲堆。

4.2 堆

4.2.1 堆简介

     所有的对象实例以及数组都要在堆上分配。堆是垃圾收集器管理的主要区域,也被称为“GC 堆”;也是我们优化最多考虑的地方。 堆可以细分为

(1)新生代

伊甸园空间(Eden空间)、幸存者空间(From Survivor)、幸存者空间(To Survivor)

(2)老年代

(3)永久代/元空间

     Java8 以前永久代,受 jvm 管理,java8 以后元空间,直接使用物理内存。因此, 默认情况下,元空间的大小仅受本地内存限制。

4.2.2 垃圾回收机制(GC)

      当对系统进行压力测试的时候,随着访问的线程越来越多(新对象越来越多),内存就会占用会越来越多,总有内存占满的时候,此时jvm就会进行垃圾回收(GC),垃圾回收过程中,一方面给新对象找位置,另一方面会对旧的还有用的类对象进行移动。

 类新建的对象,先放在伊甸园区(Eden),如果伊甸园区放得下,就直接分配内存,放不下,就做一次YGC(简单内存回收,耗费资源少,速度快)... ... 具体过程见如下流程图:

  • 特别说明:

 (1)YGC:简易垃圾回收,耗费资源少,速度快,但YGC太频繁也会影响系统效率。YGC过程见上图虚线框中。

(2)FGC:全面垃圾回收,耗费资源大,非常影响系统性能。尽量避免频繁FGC

(3)从 Java8 开始,HotSpot 已经完全将永久代(Permanent Generation)移除,取而代之的是一 个新的区域—元空间(MetaSpace)

  

4.3 重点监控指标参考

4.3.1 系统常用中间件指标

    系统常用中间件包括Tomcat(每个微服务就是一个Tomcat)等指标主要包括JVM,ThreadPool(线程池),JDBC等,具体性能指标如下:(只关注GC就是了,其他太麻烦)

一级指标二级指标单位解释
GC(本节重点)GC频率每秒多少次java虚拟机垃圾部分回收频率
Full GC频率每小时多少次java虚拟机垃圾完全回收频率
Full GC平均时长用于垃圾完全回收的平均时长
Full GC最大时长用于垃圾完全回收的最大时长
堆使用率百分比堆使用率
ThreadPoolActive Thread Count活动的线程数
PendingUser Request处于排队的用户请求个数
JDBCJDBC Active ConnectionJDBC活动连接数

(1)GC(重点):GC频率不能频繁,特别是 FULL GC 更不能频繁,一般情况下系统性能较好的情况下, JVM 最小堆大小和最大堆大小分别设置 1024M 比较合,设置方法见第五章调优部分。

(2)ThreadPool:当前正在运行的线程数不能超过设定的最大值。一般情况下系统性能较好的情况下,线 程数最小值设置 50 和最大值设置 200 比较合适。

(3)JDBC:当前运行的 JDBC 连接数不能超过设定的最大值。一般情况下系统性能较好的情况下, JDBC 最小值设置 50 和最大值设置 200 比较合适。

4.3.2 数据库指标

常用的数据库例如MySQL指标主要包括SQL、吞吐量、缓存命中率、连接数等,具体如下:

一级指标二级指标单位解释
SQL耗时微秒执行SQL耗时
吞吐量QPS每秒查询次数
TPS每秒事务次数
命中率KeyBuffer命中率百分比索引缓冲区命中率
InnoDB Buffer命中率百分比InnoDB缓冲区命中率
QueryCache命中率百分比查询缓存命中率
TableCache命中率百分比表缓存命中率
ThreadCache命中率百分比线程缓存命中率
ThreadPoolActive Thread Count活动的线程数
PendingUser Request处于排队的用户请求个数

(1) SQL 耗时越小越好,一般情况下微秒级别。

(2)命中率越高越好,一般情况下不能低于 95%。

(3)锁等待次数越低越好,等待时间越短越好。

5、JVM内存调优(更合理分配内存)

    关于项目的业务代码优化方向,在前文3.3.2中已经写得很明确了,可以分别通过nginx实现动静分离,mysql关键查询字段加索引,给数据库前面挡一个Redis缓存等来优化业务,详情可以回去查3.3.2

   本节主要写JVM内存分配来调优的方法。

5.1 IDEA设置JVM虚拟内存—Xmx、Xms、Xmn 

5.1.1 Xmx、Xms、Xmn

Xmn、Xms、Xmx、Xss 都是JVM对内存的配置参数,我们可以根据不同需要区修改这些参数,以达到运行程序的最好效果。

-Xms 堆内存的初始大小,默认为物理内存的1/64

-Xmx 堆内存的最大大小,默认为物理内存的1/4

-Xmn 堆内新生代的大小。通过这个值也可以得到老生代的大小:-Xmx减去-Xmn

-Xss(先不管) 设置每个线程可使用的内存大小,即栈的大小。在相同物理内存下,减小这个值能生成更多的线程,当然操作系统对一个进程内的线程数还是有限制的,不能无限生成。线程栈的大小是个双刃剑,如果设置过小,可能会出现栈溢出,特别是在该线程内有递归、大的循环时出现溢出的可能性更大,如果该值设置过大,就有影响到创建栈的数量,如果是多线程的应用,就会出现内存溢出的错误。

5.1.2 IDEA中设置Xmx、Xms、Xmn

进入微服务的 Configuration(如下图所示),在红圈处设置各项JVM内存

 5.2 调优案例—任意网站首页内存调优

5.2.1 调优前——JMETER压力测试

    为了演示调优效果,假设情况稍微极端一点,假装首页所在的微服务Xms只分配了100m

(1)根据2.2节内容,用JMETER进行压力测试,50个线程访问该项目首页

(2)根据3.1.1用jvisualvm监控性能

 如图可见:堆内存太小,导致频繁GC,最终内存溢出

5.2.2 调优后JVM内存情况

(1)按照4.3.1 GC指标,将Xmx,Xms,Xmn分别调整为1024m,1024m,512m

 (2)再次用jvisualvm监控性能 

4.3.1表格中的各项GC指标(GC频率,GC时长,堆使用率)都明显好转。

以上是关于压力测试 JMeter 性能监控 jvisualvm 性能调优的主要内容,如果未能解决你的问题,请参考以下文章

Jmeter4.0----监控服务器性能

压力测试研究

压力测试研究

压力测试研究

jmeter 建立一个监控测试计划

(十九)从零开始搭建k8s集群——使用KubeSphere管理平台搭建一套微服务的压力测试性能监控平台(Grafana8.5.2+influxdb2.2.0+Jmeter5.4.1)