TestTomcat示例学习笔记

简介: 快速学习TestTomcat示例

开发者学堂课程【高校精品课-厦门大学 -JavaEE 平台技术TestTomcat示例学习笔记,与课程紧密联系,让用户快速学习知识

课程地址:https://developer.aliyun.com/learning/course/80/detail/15918


TestTomcat示例

 

内容介绍:

一、代码实现

二、进行测试

三、测试结果

 

一、代码实现

第一个例子是关于 Tomcat 的并发性的测试。在前面的章节中讲到 Tomcat 的并发性的一些原理特别是关于 NIO 的原理。因为我们使用的 Tomcat 是 Tomcat的新版本,所以默认的运行模式是 NIO。我们利用 Jmeter对一个 Tomcat进行压力测试,来看测试过程中,之前讲解的 NIO的一些相关概念是如何来体现的。

来看一个利用 Jmeter性能测试的例子,该例子是为了验证在前面章节中所讲解的基于 NIO的 Tomcat的并发性原理,为了验证之前讲解的知识点,我们利用 Jmeter在短时间内大量发出 http的请求,来观察T omcat服务器是如何处理同时到来的并发性。为了验证这一点,我们写了一个简单的实验代码,该代码在 Spring MVC的TestTomcat下

image.png

代码如下:

package cn.edu.xmu.testnetty.controller;

import cn.edu . xmu.testnetty.util.ResponseUtil;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web. bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**

*@author Ming Qiu

* @date Created in 2021-6-1 22:12

**/

@Restcontroller

@RequestMapping(value = "/testtomcat",produces = "application/json;charset=UTF-8")

public class TestTomcatController {

@GetHapping("{latency}")

public 0bject sleepthread(@PathVariable long latency){

try {

TimeUnit.SECONDS.sleep(latency);

}catch (InterruptedException e) {

e.printStackTrace();

}

return ResponseUtil.ok();

}

}

可以看到在代码中非常简单,只有一个控制器,而在控制器中只有一个方法sleepthread,该方法主要内容是当客户端请求发送到服务器上时让服务器的线程睡眠指定时间,指定时间可以通过 PathVariable路径传入,作用使得在服务器上一段时间内请求不会立马处理完成会堆积在服务器上。来查看服务器如何利用 NIO来处理并发性:

在 application.yaml文件中设置了两个参数:

management:

endpoints:

web:

exposure:

include : "*"

server:

port: 8080

tomcat:

threads:

#最大工作线程数

max: 200

#最小工作线程数

min-spare: 100

这两个参数主要是关于线程池的设定,设定线程池的最大工作线程数为200,最小工作线程数为100,意味着当 tomcat服务器启动时会有100个线程,当发来的请求

超过100个后会慢慢增加到200不再增加。

 

二、进行测试

接着来看整个实验如何使用 Jmeter 来完成。

首先利用一台服务器将代码 pull下来,如图在测试的应用服务器上输入 git pull

image.png

再进行编译打包,输入 mvn package然后运行起来

输入ls

cat runjava.sh

注意因为我们需要看应用服务器的运行状况线程等,所以要用到一个工具来远程查看该服务器中 JVM的内存、线程、CPU的运行情况,在运行时需要带一些参数,所以此处写了一个 runjava.sh,里面的参数如下:

java -Xmslg-Xmxlg -Xss512k

-Dcom. sun.management.jmxremote.port=3214 \

-Dcom.sun.management.jmxremote.ssl=false  \

-Dcom.sun.management.jmxremote.authenticate=false \

-jar $1

前三个参数分别定义了堆的最大的空间、最小空间,堆运行起来时最小和最大的空间都要占用1G的内存,第三个参数s定义每个线程的堆栈数,此处每个线程的堆栈数是512k。这三个参数是最基本的参数,决定了 java虚拟机运行所占用的内存的空间。

后三个参数是为了进行远程连接来定义参数,定义了远程连接的端口是3214,定义

了不需要加密,定义了不需要用户名和密码。

使用这样的命令行去运行 java文件,为了简便写入到了一个 sh文件,使用该文件运行架包

输入./runjava.sh target/testtomcat-0.0.1-SNAPSHOT.jar

运行起来后进入另一台服务器定义 Jmeter的测试,如图输入 jmeter

image.png

在这台服务器上运行 Jmeter,在 Jmeter运行起来后可以看到里面已经定义好了一个 TestPlan

image.png

先来加入一个线程组 Thread Group,定义该线程组目的是为了让服务器阻塞,之前在代码中设定的最大线程池个数为200,为了阻塞,所以此处发400个线程,每一个服务器的请求发送后都会进行睡眠一段时间,此处睡眠3s。定义发送时间为在2s

内完成,然后循环次数为1。

image.png

定义了这样一个 Thread Group后会使得在2s内会向目标服务器发出400个 http的请求。

再来定义一个 http request的Sampler来定义如何发送请求,输入需要测试的目标服务器的IP地址172.16.0.230,应用的端口号为8080,发的请求为/testtomcat/3

image.png

再来定义一个 Response Assertion查看发出的请求是否被正常处理,在Response判断的是返回码和状态码,勾选 Response Code和Equals,返回正常状态码是200,所以定义一个 Response Assertion去判断返回值返回码是否为200

image.png

再来定义两个 Listener,第一个为 Aggregate Listener,该报表可以给出所有的请求的汇总值。第二个 Listener为 Response Time Graph,因为要关心每一个返回的时间及http的request的回应时长,该参数比较能够体现出服务器处理并发的能力。然后将它们两个进行存盘。Response Time 显示的单位是100ms,将它存成一个jmx的文件。可以在 Jmeter的图形界面中运行测试,但是为了让测试更加的公允,所以不在该服务器上运行,专门定义了三台服务器:测试服务器向目标服务器发送http请求 mybaby,现在使用的有界面的服务器只是用来监控这两个目标服务器和测试服务器的状况。将刚才定义好的 TestPlan.jmx文件拷贝到测试服务器中,输入

scp TestPlan.jmx mybaby@172.16.0.229:/home/mybaby

在目标服务器上也安装了Jmeter,所以直接将jmx文件进行拷贝,先来查看目标服

务器的状况,使用jconsole工具查看目标服务器,输入

Jconsole

Jconsole是在JDK中带来的监控的工具,可以监控本地服务器的jvm,也可以监控远端的。现在监控的是远端服务器,所以输入目标服务器的IP地址以及启动时定义的监控的端口,如图输入172.16.0.230:3214

image.png

启动后的主界面可以看到服务器的堆内存、线程、CPU的占用率等

image.png首先来查看线程的情况,点击 Threads,在线程中可以看到前面章节中讲到的Acceptor线程以及 ClientPoller线程。还有一百个nio-8080端口的线程,这就是我们定义的在线程池中的最小线程数。所以当服务器启动后可以看到这一百个线程已经全部实例化出来放入到了线程池中。

image.png

在测试服务器上运行测试,然后使用 jconsole来查看目标服务器上的内存、线程以及 CPU情况,在测试服务器上不使用界面去运行,因为测试服务器在2s内需要发出400个请求,会占用计算资源,为了不消耗它额外的计算资源,所以我们使用命令

行的方式来运行应用。所以在目标服务器上输入

Jmeter -n -t TestPlan.jmx -l result.jtl

-t从 TestPlan服务器上读出内容,然后-l将产生的结果输出到 result.jtl上。

运行起来可以看到线程数从122增加到了219:

image.png

可以看到主要增加的线程在原先从1到100的线程上增加了从101到200,多出了100个线程,这100个线程就是我们前面定义的 min到 max之间的100个线程。

此外可以看到内存开销也会增加,而且 CPU开销也会增加。当处理完后CPU的负载会降低,但是内存的值其实不会降低,除非做垃圾回收的操作。


三、测试结果

我们将测试的结果从测试服务器上拷贝到有图形界面的服务器上查看结果,先将原来的测试结果删除,然后从测试服务器上将测试结果进行拷贝,拷贝完成后可以打开 Jmeter进行查看,但是查看并不方便,所以更习惯将测试结果产生 html,这样便于在网上进行发布或者共享测试结果。输入

scp mybaby@172.16.0.229:/home/mybaby/*.jtl

ls

cd..

ls

cd Downloads/

ls

cd apache -jmeter-5.4.1

cd bin

ls

vim user.properties

所以我们依然使用 Jmeter的命令将测试结果转换为 html,在执行转换前需要修改在本地安装的Jmeter的一些设置,因为它默认的单位是1min,而我们刚才看到的测试时间请求是在2s内发出的,所以要修改 Jmeter下的 user.properties文件。

进入后修改 overall_granularity单位改为100ms。修改完后再使用 Jmeter产生html,输入

cd

ls

rm -r result

jmeter -g result.jtl -o result

使用-g 读取 result.jtl,然后使用-o输出到 result目录下,输出完后可以到 result目录下可以看到一个 index的 html文件,打开后首先看到测试的汇总结果

image.png

可以看到所有的 http的 request返回都是正常的。一共发出了400个请求,错误率是0,平均值是4952.4ms,最小的是3394ms,因为在服务器上都需要睡眠

3000ms,所以再加上它的一些延迟,所以最小也是3394ms。

最大的是6967ms,说明有被阻塞的内容,发出请求后其实服务器上已经没有任何的线程供服务了,需要得到前面的线程完成后,所以达到了6000ms。这是它的汇总情况。

再来查看它的时间:

image.png

第一个看到的时间是 Response Times 和它的时间的关系,可以看到第一个请求返回回来的时间大概是5点10分29,Response Times是3867ms,说明该批请求没有被阻塞,因为在服务器上本身就睡眠了3000ms。第二批的 Response Times是在10分32秒,即3s后才收到,那么它的 Response Times都是6019ms,说明被阻塞了一轮。接着来查看比例,下图是随着时间的比例,与上图类似:


image.png

显示了它的最小值和最大值以及它的95%、99%在不同时间段的情况。该图非常明显,可以看到在第一轮时所有返回的 Response都在3000ms下,无论是最小值、最大值、平均值都是3000ms。到了第二轮返回时所有的值都在6000ms,说明所有的

线程都睡眠。我们可以看到整个时长大概运行6s左右,因为存在延迟关系。

下图是它的活动线程与时间的关系:

image.png

可以看到在5点10分29时是400个线程,随着不断有请求的完成,活动线程在不断减少,所以到了第二点时完成了100个线程时还剩下300个线程。

下图是 Response Times和比例之间的关系:

image.png

可以看到50%的请求都在4000ms下,一共发出了400个请求,50%就是前200个请求是在4000ms下,说明没有被阻塞。而剩下的请求可以看到有一个迅速的跳升,跳到了5000多ms甚至是6000ms,说明剩下50%的线程都被阻塞。

下图是活动线程数与反应时间的关系:

image.png

因为我们是在2s内发出了400个线程,所以当400个线程全部发出时可以看到Response Time都是在3000多 ms,所以最开始返回的线程是直接没有阻塞的。前面200个线程全部都返回而这200个线程基本都是在3000、4000ms,没有阻塞就返回。当活动线程数少于200个,后面的200个线程基本都是在5000、6000ms才返回,虽然一开始都在2s内发出,但是它们会被阻塞,所以需要5000-6000ms才能完成。

下图是 Response Time 的分布图,可以明显看到反应时间被分为了两批,一批是

3000-4000ms,一批是5000-6000ms。

image.png

50%是3000-4000ms,50%是5000-6000ms。

相关文章
|
2月前
|
传感器 数据处理
示例三、光照度测试仪
示例三、光照度测试仪
26 1
|
Cloud Native 架构师 Devops
几个测试示例分享 | 学习笔记
快速学习几个测试示例分享
93 0
几个测试示例分享 | 学习笔记
|
Kubernetes Cloud Native 架构师
示例介绍|学习笔记
快速学习示例介绍
82 0
示例介绍|学习笔记
|
前端开发 Java 网络架构
合法性检查示例|学习笔记
快速学习合法性检查示例
92 0
合法性检查示例|学习笔记
|
Kubernetes Cloud Native 架构师
示例介绍 | 学习笔记
快速学习示例介绍
79 0
示例介绍 | 学习笔记
|
Cloud Native 架构师 机器人
几个测试示例分享|学习笔记
快速学习几个测试示例分享
87 0
几个测试示例分享|学习笔记