业务背景:
模拟100辆车,同时以固定的频率向MQTT发送一定格式的数据,数据包含序列号、车辆编号、时间戳及其他车辆信息。
需求分析:
- 100辆车,即100个线程同时并发
- 每辆车都以固定的频率发送数据,如5s、10s等
- 每辆车每次发送数据中的序列号、时间戳是不一样的
- 每辆车每次发送的车辆编号是一致的
准备工作
1. 引入插件
Jmeter中没有MQTT插件,需要引入相关插件
- 如果安装了插件管理器(plugins-manager),在Available Plugins中搜索MQTT后进行安装即可
- 如果没有安装插件管理器,也可以直接下从 GitHub 上下载最新版本插件 mqtt-xmeter-2.0.2-jar-with-dependencies.jar。
该插件支持 JMeter 3.2 及以上版本
下载后将插件 jar 包拷贝到 JMeter 的插件目录:$JMETER_HOME/lib/ext,然后重新启动 JMeter。
安装成功后,会有4个Sampler
2. 引入第三方工具库
- 下载第三方开源工具库hutool-core的jar包
下载地址:Download | hutool-core - 将jar包放到 JMeter 的lib目录:$JMETER_HOME/lib,然后重新启动 JMeter。
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool的目标是使用一个工具方法代替一段复杂代码,从而最大限度的避免“复制粘贴”代码的问题,彻底改变我们写代码的方式。
设计和编写Jmeter脚本
1.搭建脚本结构
- 100辆车的编号均不同,可通过Config Element - Counter来计数生成
- MQTT Connect 和 MQTT DisConnect 均执行一次,可以通过Logic Controller - Once Only Controller控制
- MQTT Pub Sampler需要不断的以一定的频率发送,通过Logic Controller - Loop Controller 控制执行次数,通过Timer - Constant Timer控制发送频率
脚本结构如下:
2. 设置Counter
设置固定的格式,供后续生成车辆编号使用
3. 配置MQTT Connect
填写IP和端口,MQTT默认端口是1833,如需要登陆,填写用户名和密码。
4. 构造发送数据
填写Topic Name。发送内容选择String,这里引用参数${text}。
在BeanShell PreProcessor中预处理数据
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.ByteUtil;
import java.nio.ByteOrder;
import java.util.concurrent.TimeUnit;
try {
//读取数据模板文件
byte[] aic5s =ResourceUtil.readBytes("D:\\template\\temp1.bin");
//处理文件内容,添加序列号,车辆vin、时间等信息
DateTime now = DateTime.now();
int ts = (int) (now.getTime() / 1000);
byte[] tsBytes = ByteUtil.intToBytes(ts, ByteOrder.BIG_ENDIAN);
byte[] t = String.valueOf(ts).getBytes();
//将序列号和时间戳放到指定的位置
System.arraycopy(tsBytes, 0, aic5s, 0x03, tsBytes.length);
System.arraycopy(t, 0, aic5s, 0x45, t.length);
System.arraycopy(t, 0, aic5s, 0x56, t.length);
//生成车辆的VIN号,seq变量来自counter
String vin="VEHICLETEST"+ vars.get("seq");
byte[] cnum =vin.getBytes();
//将VIN号放到指定的位置
System.arraycopy(cnum, 0, aic5s, 0x28, cnum.length);
//将处理好的内容转为字符串,并放到变量text中
String content = new String(aic5s);
vars.put("text",content);
}
catch (Exception e) {
log.info("异常:" + e);
}
运行和调试脚本
Thread Group中线程数设置为3,1s启动;Loop Controller设置为2
查看执行结果,同一个clientId,每次发送的车辆编号是同一个,每次的序列号和时间戳都会变化,符合要求。