4 自定义Jmeter采样器

步骤 动作
1 创建一个Java类并继承AbstractJavaSamplerClient
2 实现setupTest方法,用于初始化
3 实现runTest方法,用于执行具体的请求
4 实现teardownTest方法,用于清理资源
5 编译并将生成的jar文件放入JMeter的lib/ext目录下
6 在JMeter中创建一个新的线程组
7 添加一个Java Request到线程组中,并设置相应的参数
8 运行测试,查看结果

步骤 1: 创建一个Java类并继承 AbstractJavaSamplerClient

引入对应的依赖

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>4.0</version>
</dependency>

<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>4.0</version>
</dependency>

首先,我们需要创建一个Java类,并继承 AbstractJavaSamplerClient。这个类将成为我们自定义Sampler的入口点。

1、setupTest 用来做一些初始化的操作,每一线程只会调用该方法一次。

2、teardownTest 用来做一些清理的操作,每一线程只会调用该方法一次。

3、getDefaultParameters 设置sample的参数以及默认值,这个方法设置的参数会显示在Java request组件的界面上。

4、runTest 这个方法就是sample的核心方法,每次迭代都会调用,并且返回SampleResult对象。由于该方法是抽象方法,所以自定的sample一定要实现该方法,其他方法可根据情况选择是否重写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package lym.iflytek.mt_scylla;

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 TestSample extends AbstractJavaSamplerClient {
private IatDemo iat;#业务类,具体代码不再贴出来

public Arguments getDefaultParameters() {
/*
这个方法由JMeter调用,添加的Arguments参数会在界面上展示出来,可以设置默认值。
* */
Arguments arg = new Arguments();
arg.addArgument("addr", "");
arg.addArgument("appid", "");
arg.addArgument("token", "");
arg.addArgument("rate", "");
arg.addArgument("filePath", "");
arg.addArgument("printLog", "false");
arg.addArgument("encoding", "utf-8");
arg.addArgument("costTimeType", "3");
return arg;
}


public void setupTest(JavaSamplerContext context) {
/*进行初始化操作,每一个线程只执行一次*/
String addr = context.getParameter("addr");
String appid = context.getParameter("appid");
String token = context.getParameter("token");
String rate = context.getParameter("rate");
String printLog = context.getParameter("printLog");
String costTimeType = context.getParameter("costTimeType");
iat = new IatDemo(addr, appid, token, rate, printLog, costTimeType);
System.out.println(Thread.currentThread().getName()+":初始完成");

}

public void teardownTest(JavaSamplerContext context){
/*做一些清理操作,每个线程只执行一次*/
try {
iat.UninitializeEx();
System.out.println(Thread.currentThread().getName()+":逆初始化完成");
} catch (IflytekException e) {
getNewLogger().error(e.getMessage(), e);
}
}

public SampleResult runTest(JavaSamplerContext javaSamplerContext) {
/*每次迭代都会调用,并且返回SampleResult对象,该对象保存了每次运行的执行结果*/
String filePath = javaSamplerContext.getParameter("filePath");
String encoding = javaSamplerContext.getParameter("encoding");
String costTimeType = javaSamplerContext.getParameter("costTimeType");
#SampleResult ,用来保存每次运行的结果,以便JMeter进行数据统计。
SampleResult sampleResult = new SampleResult();
#通过参数控制运行时间的统计范围,如果你的业务没那么复杂,
#完全可以在runTest开始时设置开始时间,方法结束时设置结束时间。
if (costTimeType.equals("1")) {
sampleResult.sampleStart();#设置运行的开始时间
}
try {
String allresult = iat.start(filePath, sampleResult);

sampleResult.setSamplerData(filePath);#设置输入数据
sampleResult.setDataType(SampleResult.TEXT);#设置数据类型
sampleResult.setResponseData(allresult, encoding);#设置sample接收到的数据
sampleResult.setSuccessful(true);#设置sample执行结果
sampleResult.setResponseCodeOK();#设置sample执行状态码

} catch (Exception e) {
sampleResult.setSuccessful(false);
sampleResult.setResponseCode("500");
sampleResult.setResponseMessage(e.getMessage());
getNewLogger().error(e.getMessage(), e);
}
if (costTimeType.equals("1")) {
#设置运行的结束时间,结束时间-开始时间,就是整个sample的运行时间
#(JMeter就是用这个时间来计算平均响应时间的)。可以根据实际情况,设置在不同的位置。
sampleResult.sampleEnd();
}

if (sampleResult.getStartTime() == 0) {
sampleResult.sampleStart();
}

if (sampleResult.getEndTime() == 0) {
sampleResult.sampleEnd();
}
return sampleResult;
}

public static void main(String[] args) {
IflytekSample sample = new IflytekSample();
Arguments arg = new Arguments();
arg.addArgument("addr", "192.168.0.1:1234");
arg.addArgument("appid", "00000000");
arg.addArgument("token", "11111111");
arg.addArgument("rate", "41000");
arg.addArgument("filePath", "1.wav");
arg.addArgument("printLog", "true");
arg.addArgument("costTimeType", "2");

JavaSamplerContext javaSamplerContext = new JavaSamplerContext(arg);
sample.setupTest(javaSamplerContext);
SampleResult sampleResult = sample.runTest(javaSamplerContext);
System.out.println(sampleResult.getResponseDataAsString());
sample.teardownTest(javaSamplerContext);

}


步骤 2: 实现 setupTest方法

setupTest方法在每个线程开始之前执行,用于初始化一些资源或设置。在这个方法中,你可以进行一些预处理的操作。

1
2
3
4
5
@Override
public void setupTest(JavaSamplerContext context) {
// TODO: 初始化操作
}
1.2.3.4.

步骤 3: 实现 runTest方法

runTest方法是实际执行请求的地方。在这个方法中,你可以使用各种HTTP或其他类型的客户端库来发送请求,并处理响应。

1
2
3
4
5
6
7
8
9
10
@Override
public SampleResult runTest(JavaSamplerContext context) {
SampleResult result = new SampleResult();
result.sampleStart(); // 标记请求的开始时间

// TODO: 执行实际的请求操作

result.sampleEnd(); // 标记请求的结束时间
return result;
}

步骤 4: 实现 teardownTest方法

teardownTest方法在每个线程结束之后执行,用于清理资源或做一些收尾的工作。

1
2
3
4
@Override
public void teardownTest(JavaSamplerContext context) {
// TODO: 清理操作
}

步骤 5: 编译并将生成的jar文件放入JMeter的lib/ext目录下

完成以上步骤后,我们需要将代码编译成jar文件,并将该文件放入JMeter的lib/ext目录下。这样,JMeter就能够找到并加载我们自定义的Sampler。

步骤 6: 在JMeter中创建一个新的线程组

在JMeter中,我们需要创建一个新的线程组来运行我们的测试。线程组表示一组并发的用户,可以设置线程数、循环次数等参数。

步骤 7: 添加一个 Java Request到线程组中,并设置相应的参数

在线程组中,我们需要添加一个 Java Request。在该请求中,我们需要设置一些参数,例如类名、方法名等,以告诉JMeter我们要运行哪个自定义的Sampler。

步骤 8: 运行测试,查看结果

最后,我们可以运行测试并查看结果。在结果树中,我们可以看到每个请求的响应时间、错误率等信息。

5 创建Jmeter集群

原理

1、Jmeter分布式测试时,选择其中一台作为控制机(Controller),其它机器做为代理机(Agent)。

2、执行时,Controller会把脚本发送到每台Agent上,Agent 拿到脚本后开始执行,Agent执行时不需要启动Jmeter,只需要把jmeter-server.bat文件打开,它应该是通 过命令行模式来执行的。

3、执行后,Agent会把结果回传给Controller,Controller会收集所有Agent的信息并汇总。

Slave配置

配置Slave的地址名称。Jmeter/bin/jmeter.properties,找到”remote_hosts=127.0.0.1”,把这一行修改为”remote_hosts=192.168.8.149:1099

1
2
3
4
5
6
# Remote Hosts - comma delimited
remote_hosts=127.0.0.1:1099
#remote_hosts=localhost:1099,localhost:2010

# RMI port to be used by the server (must start rmiregistry with same port)
server_port=1099

启动jmeter slave

1
jmeter-server

Master配置

GUI方式:可以通过配置文件决定连接的remote。Jmeter/bin/jmeter.properties,找到”remote_hosts=127.0.0.1”,把这一行修改为”remote_hosts=192.168.8.149:1099,192.168.8.174:1099,1099是端口号,可以随意自定义。如果有多台代理机,这里需要把所有的代理机的IP地址和端口号都加入进来。

1
remote_hosts=192.168.8.149:1099,192.168.8.174:1099

命令行方式

1
jmeter -n -t Test.jmx -l test_results.csv -JserverAddr=123 -R remote_host1,remote_host2

其他问题

一个比较标准的参数解决方案如下:

1
Jserver.rmi.ssl.disable=true -Jjava.net.preferIPv4Stack=true -Jjava.net.preferIPv6Addresses=false -Jsearch_paths=/home/admin/run

配置user.properties关闭http用户校验

1
server.rmi.ssl.disable=true

配置system.properties中ipv4网络协议

1
2
java.net.preferIPv4Stack=true
java.net.preferIPv6Addresses=false