Oracle Fusion Middleware
JMeter使用
概述
JMeter是常用压力测试工具,基于java开发,属于Apache基金开源项目。本文介绍JMeter基本使用方法。包括以下内容
- JMeter下载安装
- JMeter使用方法
- 开发JMeter自定义Sampler
下载安装
- 下载
jmeter-3.1
http://mirrors.cnnic.cn/apache//jmeter/binaries/apache-jmeter-3.1.zip
- 安装
直接解压,启动bin/jmeter.bat即可
软件启动后界面如下
使用
这里以一个简单Rest接口为例,接口信息如下:
接口名称:获取调试人员列表
接口地址:http://bpmdev.smec-cn.com:8011 /InstDebugDev/instDebugGetPerlist/instDebugGetPerlistService
调用方式:POST
输入参数:{"org_id":"分公司编号"}
其他说明:调用该接口需在http header上加一个属性DF_KEY。值为登录后服务器返回的token
- 添加线程组
线程组的概念可以理解为表示一个或者多个用户的多次并发请求。JMeter会为每一个用户启动一个线程。
创建完后可以更改线程组名称,便于理解
2.添加Http 请求Sampler
Sampler是JMeter中很重要的一个概念,可以理解为“要干什么事,要测什么内容”,是要测Http请求还是要测Ftp请求还是要测JDBC请求,如果要测的内容在列表里面没有,甚至可以自己通过java实现,然后选择Java请求的Sampler实现,这个下面也会讲到。
3.添加报告
4.添加完报告后就可开始测试
在线程组上右键,配置线程属性
线程数:代表用户数
Ramp-Up Period:启动这些线程使用时间,如果设为1表示1秒内启动所有线程
循环次数:表示每个用户请求次数
总共的请求次数=线程数*循环次数
在线程组上右键->Start或者点击工具类上
图标启动压力测试
所有的请求都跑完之后,在报告里可以查看本次压测统计数据
相关参数解释:
Label:每个 JMeter 的 element(例如 HTTP Request)都有一个 Name 属性,这里显示的就是 Name 属性的值
#Samples:表示你这次测试中一共发出了多少个请求,如果模拟10个用户,每个用户迭代10次,那么这里显示100
Average:平均响应时间——默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,也可以以Transaction 为单位显示平均响应时间
Median:中位数,也就是 50% 用户的响应时间
90% Line:90% 用户的响应时间
Note:关于 50% 和 90% 并发用户数的含义
Min:最小响应时间
Max:最大响应时间
Error%:本次测试中出现错误的请求的数量/请求的总数
Throughput:吞吐量——默认情况下表示每秒完成的请求数(Request per Second)
KB/Sec:每秒从服务器端接收到的数据量
5.添加结果数
前面我们测试但无法看到返回结果,如果想要看响应数据需要添加结果树。
线程组右键->添加->监听器->查看结果树
再次测试就能看到结果
从结果可以看出本次调用失败,中文可能有点乱码,目前没有找到解决方法。前面接口说明里提到该接口需要提供一个名称为DF_KEY值为token的Http Header。但在该测试中并未设置该字段,需要设置下该字段。
6.添加Http Header
要添加http header,在线程组上右键->添加->配置元件->http 信息头管理器
需要把心添加的HTTP消息头管理器移动到http上方
再次测试即可
自定义Sampler
如果你需要压测的任务是JMeter自带Sampler列表没有的,这时你需要自己实现一个Sampler。
场景:你要测试一个生成MD5的java方法性能,需要借助JMeter测试。
- 依赖包
将JMeter目录下lib目录中所有jar包到你的build path中,包括ext目录下的jar包。
- 继承类AbstractJavaSamplerClient,并重写以下方法
public Arguments getDefaultParameters();设置可用参数及的默认值,返回给JMeter,JMeter会根据该返回值生成配置界面传给程序。
public void setupTest(JavaSamplerContext arg0):每个线程测试前执行一次,做一些初始化工作;
public SampleResult runTest(JavaSamplerContext arg0):开始测试,从arg0参数可以获得参数值;
public void teardownTest(JavaSamplerContext arg0):测试结束时调用;
- 实现代码
import java.security.MessageDigest;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
public class MD5Sampler extends AbstractJavaSamplerClient {
public MD5Sampler() {
super();
}
/**
* 生成MD5方法
* @param s
* @return
*/
public String getMD5(String s) {
char hexDigits[] =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
'E', 'F' };
try {
byte[] btInput = s.getBytes("utf-8");
MessageDigest mdInst = MessageDigest.getInstance("MD5");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 测试执行方法
* @param javaSamplerContext
* @return
*/
public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
String sampleInput = javaSamplerContext.getParameter("需要生成的MD5字符串");
//result结果将会输出到结果树种
SampleResult result = new SampleResult();
result.setSampleLabel("MD5生成测试");
try {
String md5 = this.getMD5(sampleInput);
result.setResponseData(md5, null);
result.setDataType(SampleResult.TEXT);
result.setSuccessful(true);
} catch (Exception ex) {
result.setSuccessful(false);
ex.printStackTrace();
} finally {
result.sampleEnd();
}
return result;
}
/**
* 获取输入参数列表
* @return
*/
@Override
public Arguments getDefaultParameters() {
Arguments params = new Arguments();
params.addArgument("需要生成的MD5字符串", "测试样例字符串");
return params;
}
/**
* 每个线程测试前执行一次,做一些初始化工作
* @param javaSamplerContext
*/
@Override
public void setupTest(JavaSamplerContext javaSamplerContext) {
System.out.println("开始调用");
super.setupTest(javaSamplerContext);
}
/**
* 测试结束时调用
* @param javaSamplerContext
*/
@Override
public void teardownTest(JavaSamplerContext javaSamplerContext) {
System.out.println("调用结束");
super.teardownTest(javaSamplerContext);
}
}
- 打包成jar包并将该jar包放在JMeter安装目录下lib\ext下。重启JMeter
- 启动JMeter,新建一个线程组,创建一个Java请求的Sampler,可以看到上面创建的自定义Sampler
其中参数列表中就是getDefaultParameters中返回的参数列表。
配置一个50个线程,200循环次数的测试,也就是10000次调用,并创建结果树和报表查看结果。
可以看到,生成md5的代码基本上是不耗性能的。其实在开发当中,我们以为会耗性能的代码其实对于计算机而言是微不足道的,经过上面测试,应该对这个有所体会,就算把请求次数增大,对性能的影响还是微乎其微的。