使用JMeter进行压力测试
说到压力测试,一般第一反应都是LoadRunner.这个软件也确实是自动化测试的一个事实标准.无奈这个软件太过庞大,以及不能在MacOS上使用.我由于项目的需要,需要对一个模块的WebServcie接口做压力的测试,于是就找到了另外一个神器JMeter. JMeter是Apache组织开发的基于Java的压力测试工具.它是由JAVA编写的,可以跨平台.最初只能测试Web应用,现在可以进行各种的压力测试,包括但不限于JAVA小程序,CGI脚本,JAVA RMI调用,数据库,FTP服务等等. 并且它的操作非常简单,通过几部的配置就可以创建一个完整的压力测试用例.
JMeter安装
JMeter是由JAVA编写的,所以需要依赖JDK的运行环境,最新版的JMeter需要JDK1.6以上的支持.
JMeter的软件可以通过官网下载.直接下载编译后的压缩包,然后在终端中输入:unzip apache-jmeter-2.13.zip
进行解压
而后在终端中执行./jmeter
即可启动主界面.
进行Web的压力测试
JMeter中最小的单位就是元件.你可以给你的测试计划中增加若干的元件,每一个元件其实就是一个步骤. JMeter中设置了各种不同的元件:有设置用户的,有设置定时器的,有设置前后置处理的,有设置断言的还有设置监听器的.通过这些不同的元件的组合,我们就能很很容易的组合出更多不同的压力测试用例.
我们以最简单的Web服务器的压力测试为例,来演示下如何使用JMeter设置测试用例.
设置线程组(模拟用户)
压力测试不同于功能测试,软件的正确性并不是它的测试重点。它所看重的是软件的执行效率,尤其是短时间内访问用户数爆炸性增长时软件的响应速度.因此就需要同时模拟多个用户对系统进行请求. 因此,一般设置测试计划的第一步都是创建一个线程组,用来模拟多个用户的操作.
而后就需要设置线程组的一些属性.
- 线程数:相当于是模拟用户的数量.
- 准备时长:表示线程之间间隔多少时间,单位是秒.0就表示了所有的线程并发发送请求,否则就是每个线程间隔几秒发送请求
- 循环次数:表示每个线程执行几次
- 调度器:就是创建线程的schedule.
- 在取样器错误后执行的操作:表示线程出现错误后执行的操作.比如继续,或者停止线程,或者测试
设置HTTP请求
这里我们使用最简单的用例进行测试——访问我的博客的首页,测试QPS(Query Per Second 每秒查询率)的情况.
因此,接下来我们需要增加的就是在线程组上面右键—-添加—-Sampler—-HTTP请求.
在JMetaer中取样器(Sampler)就是与服务器进行交互的元件.一个取样器通常会进行三个部分的工作:
- 向服务器发送请求
- 记录服务器的响应数据
- 记录响应的时间信息
这里我设置了:
- 服务器名称: sunxiang0918.cn
- 端口号: 80
- HTTP请求实现: JAVA
- 协议: http
- 方法: GET
- ContentEncoding: UTF-8
- 路径: /
其实这样就算是完成了一个HTTP请求的设置了.这个时候我们就可以保存这个测试用例到一个JMX文件
中.然后执行这个测试用例了. 不过,由于我们还没有配置监听器元件,因此,现在运行的话.我们是看不到任何的结果的.
请求参数模板化
在实际的使用中,我们的请求中可能有不同的参数,并且这些参数可能是不相同的.这就需要把参数模板化.
在JMeter中,参数的语法是: ${xxxx}
其中的xxxx
即为参数名. 通过这个语法,就可以在整个请求中调用参数的值. 只要我们对这些参数进行赋值即可.
比如在这里我们增加一个Random Variable
.这个表示的是随机的给一个变量进行赋值.
我们在这里设置了一个keyword
的变量,其值为0
到100
间的随机数.随机方式采用默认的.
然后在请求中增加一个请求的参数:
执行测试计划,会发现请求的URL就会变成:GET http://sunxiang0918.cn/?aaaaa=xxxx49
,后面的数字就是随机.
除了随机变量或用户定义的变量外.还可以读取CSV文件,通过CSV Data Set Config
,可以读取CSV文件,并且制定每一列的变量名是什么.这样就可以在请求的时候预设多个变量值.
增加响应断言
为了判断结果的正确性,我们有时需要增加响应的断言.比如响应代码必须是200才作数. JMeter中有一个元件就叫做响应断言
.这个就可以加在HTTP请求的后面,用来判断结果是否正确.
在这里我只增加了一个最简单的通过响应代码来判断请求是否正确.
除此之外,它还能通过响应的内容,响应的头信息等来进行判断.功能非常的强大.
设置结果监听器
为了我们能查看到请求的结果,我们需要再添加监听器. 在这里我们增加三个结果监听器:察看结果树
图形结果
以及聚合报告
查看结果树
可以查看到每一次请求的具体情况,包括了请求参数,结果反馈,请求时间等等. 图形结果
可以以图形的方式展现请求的中和结果. 聚合报告
会展示本次测试计划所有的请求的一个聚合的结果.
这几个结果监听器都不需要什么设置.增加后,即可再执行一次测试计划.里面就会有结果了.
我们先来看查看结果树
. 它显示了这次请求的所有信息.比如开始时间,线程名字,完成用时,请求大小,反馈大小,反馈代码,采样次数,错误信息,反馈头信息,反馈体等等. 通过这个列表,我们就能很清楚的知道所有请求的大概情况.
然后就是图形结果
从这个图上就能很清楚的看出整个请求和响应的趋势.
最后就是聚合报告
. 它用表格的形式展示了本次测试的总体情况.
LabelSamplesAverageMedian90%Line95%Line99%LineMinMaxErrorThroughputKB/sec名称采样请求数平均响应时间中位数90%用户响应时间95%用户响应时间99%用户响应时间最小响应时间最大响应时间错误请求百分比吞吐量,每秒完成请求数每秒接收数据量HTTP请求20081166015371886242227534240.00%15.8/sec542.3
限制QPS
为了了解博客的首页在负载达到30QPS时的响应时间,我们就需要控制向博客首页发送请求的负载为固定的30QPS. JMeter提供了一个非常有用的定时器:Constant Throughput Timer
(常数吞吐量定时器),通过该定时器可以方便的控制给一个采样器发送请求的吞吐量.
首先是Target throughput
目标吞吐量,需要注意的是这个的单位是分钟. 比如我们要测试的是30QPS,那么一分钟的吞吐量就是 1800. 而Calculate Throughput based on
有五个选项:
- This thread only:控制每一个线程的吞吐量.这个时候,总吞吐量就是
Target throughput
乘以线程数 - All active threads:设置总体的吞吐量,它会把
Target throughput
分配到每一个活跃的想成上. - All active threads in current thread group.设置总体的吞吐量,它会把
Target throughput
分配到每一个活跃的想成上.当一个测试计划中只有一个测试组的时候,效果和All active threads
是一样的. - All active threads(shared):与
All active threads
的区别在于,每个活跃线程都会在所有活跃线程上一次运行结束后等待一定的时间后再次运行. - All active threads in current thread group(shared):与
All active threads in current thread group
的区别在于,每个活跃线程都会在所有活跃线程上一次运行结束后等待一定的时间后再次运行.
因此,我们这里选择了All active threads
.
需要注意的是:这个常量吞吐量定时器只有在线程组中产生了足够多的请求的时候才有意义.否则,就算设置了这个Target throughput
,也有可能由于线程数和请求数不够,而打不到预期的目标.
在这个基础上再跑一次的结果为:
LabelSamplesAverageMedian90%Line95%Line99%LineMinMaxErrorThroughputKB/sec名称采样请求数平均响应时间中位数90%用户响应时间95%用户响应时间99%用户响应时间最小响应时间最大响应时间错误请求百分比吞吐量,每秒完成请求数每秒接收数据量HTTP请求30091072315251812326830592550.00%11.2/sec387.0
由此可见,在这里访问github.io,确实相当的慢啊….
总结
这里只是简单的展示了一下JMeter的用法,其实对其他的压力测试,比如WebService
,Restful
,RMI
等的测试都可以参照这个步骤,增加不同的元件即可.