110 lines
4.9 KiB
Markdown
110 lines
4.9 KiB
Markdown
# 使用 JMeter 做简单的压测
|
||
|
||
Date: 2022/05/12 09:10
|
||
|
||
ZhouXY
|
||
|
||
---
|
||
|
||
## 需求
|
||
|
||
1. 模拟:模拟生产者往 ActiveMQ 中发消息
|
||
2. 并发:每 5 分钟发 15000 条数据
|
||
3. 持续时长:持续 2 个小时
|
||
4. 消息格式:消息内容为 JSON 数据,包括 **`dev_code`** *(设备号)*、**`time`** *(当前时间)*、**dev_name** *(设备名称)*
|
||
- **dev_code** 从 100 个字符串中随机选择
|
||
- **time** 为当前时间的字符串,格式为 `yyyy-MM-dd HH:mm:ss.SSS`
|
||
- **dev_name** 为 `DEV_NAME` 加上递增的整数
|
||
|
||
## 步骤
|
||
|
||
1. 打开 JMeter,有一个默认为空的测试计划 Test Plan,修改其名称,如:ActiveMQ 压测 Demo
|
||
2. 在测试计划中创建一个线程组
|
||
3. 在线程组中创建事务控制器
|
||
4. 在事务控制器中一次创建 **计数器**、**BeanShell 取样器**、**JMS Publisher**
|
||
5. 在 JMS Publisher 中创建一个 `Precise Throughput Timer`,即准确的吞吐量定时器。
|
||
|
||
## 线程组和定时器
|
||
|
||
线程组和定时器控制并发量和持续时间。
|
||
|
||
由于 JMeter 创建线程是不间断的,所以需要定时器。这里使用 Precise Throughput Timer 可以比较好地控制。
|
||
|
||
按照要求,测试结束时,应发送了 360000 条数据,实际测试可能会多几百条,误差还是相对较少的。
|
||
|
||
### 线程组
|
||
|
||
1. 线程属性的`线程数`填 500,`Ramp-Up时间(秒)`填 10,表示 **10 秒内创建 500 个线程**。我一开始直接填 300 秒(5 分钟)创建 15000 个线程,结果发送一段时间后,就会出现部分数据发送失败,暂时不知道原因。请根据自己的需要调整。
|
||
2. 循环次数勾选 `永远`
|
||
3. 勾选下面的`调度器`选项,`持续时间(秒)`填 `7200`,表示 2 个小时
|
||
|
||
### 定时器
|
||
|
||
1. 目标吞吐量:15000
|
||
2. 吞吐量周期:300
|
||
3. 测试持续时间:7200
|
||
4. 其它保持不变即可
|
||
|
||
## 计数器
|
||
|
||
由于 **dev_name** 中需要一个递增的整数,所以我们设置了计数器,最小值我设置为 1,递增为 1,引用名称为 `num`。
|
||
|
||
这样,JMS Publisher 中的内容就可以以 `${num}` 的形式使用该计数器的值。
|
||
|
||
## BeanShell 取样器
|
||
|
||
BeanShell 取样器可以使用 Java 的写法生成数据,然后放到“变量”中,供其它取样器使用。**dev_code** 的值是从 100 个字符串中随机选择,BeanShell 取样器要做的就是从 100 和字符串中随机选择一个,放到变量 `dev_code` 中。脚本如下所示:
|
||
|
||
```java
|
||
import java.util.Random;
|
||
|
||
String[] devCodes = {
|
||
"A1p8wu9iBt", "A9VzXBaFIJ", "ASKb08oVnr", "Ae2ifNTN9b", "AgpzQ8aNbt",
|
||
"Bh5CBlP4ot", "Bo7RE8Sl8Y", "BrxCJ85ETL", "BL3HF89URd", "Bs1Ij2LAHj",
|
||
"CzLJmZrfkM", "C4rmU81HCC", "CyH5il1W39", "Cn8D2aiVV8", "CX8nbIsB50",
|
||
"D4oGv91ePj", "DGxYsqTcXK", "DUyFsC5Drx", "DR6MpJJaDj", "DuH37e1jZ8",
|
||
"EYvQ6sJvhU", "E8FgaOGEc9", "Ey4Wfjj1gs", "EKC1oKFvmb", "Ec2vHlrBb4",
|
||
"FWN6vGoqnQ", "F8BbYS9l0I", "FzWxDecBOe", "FnjId6wkyw", "FJXFE9fcVg",
|
||
"GbhQiY6RIf", "GBHdz2QifF", "Gxy9Nr7SE6", "GyUtw6nbte", "GogX2WX36O",
|
||
"HxagCSigXb", "HWMhH7jWar", "H4sGFmP1Oi", "HIlL8LgwpQ", "HxB1KIPmU9",
|
||
"I57qZxE3FU", "I6ghZSfeQS", "IE0o7RF4jD", "IahpQHwBeq", "IaIAIEPHeA",
|
||
"JBfTrmIMAM", "JuZPRFKLqv", "J514XwwJRh", "JIXav0i4sF", "JhOW0JqoTX",
|
||
"KcWpYmJ5O6", "KDIpmm8IM8", "KIM10uv0HC", "KNtsRI9nWS", "KiuaJ6axgB",
|
||
"LxV7kYcam8", "LPxgMsC9v0", "LHT2biCDUg", "LKTGKDRh7q", "LY7XgPcpHi",
|
||
"MFV3F7iZTW", "MUEBypwmK9", "MRKFcfPHQt", "MVHMA2icrK", "MGivy5wulf",
|
||
"NzuMjdPtns", "N3bGBHlVnn", "NQc9WVJcO2", "N9sV5JrjYw", "NrdFpm8SLc",
|
||
"OncgB1XRyt", "OkvCZNPBft", "O2xfZ2UNTy", "OHYm0xpbsN", "ORNSHzP1TG",
|
||
"PSvqG70T2e", "PvZL2OpA1T", "PpqjV93fl8", "PAPtqDahqS", "Py6pWjF7hi",
|
||
"QyrG0AYK0T", "QOVP9hKuIN", "QNT02cVBU2", "QjyWUmVCpl", "QF5vNIMKxM",
|
||
"RrZZAxOSJJ", "RCfXSwKY1i", "R0XGiHreU4", "RmC7iQvIuU", "RdtzQ7T9cK",
|
||
"SM9dzy31hS", "SI9SykQ8Ex", "SCx73KMyOT", "SKXwIrPJdr", "SlVDhvrb4d",
|
||
"T4qXJdmRD9", "TKiDzobds3", "T8TRTHiQ42", "TKvTq2p7Dg", "TPYxtA1wz4"
|
||
};
|
||
Random random = new Random();
|
||
|
||
vars.put("devCode", devCodes[random.nextInt(devCodes.length)]);
|
||
```
|
||
|
||
这样,JMS Publisher 中的内容就可以以 `${devCode}` 的形式使用随机选取的字符串。
|
||
|
||
## JMS Publisher
|
||
|
||
- Initial Context Factory:org.apache.activemq.jndi.ActiveMQInitialContextFactory
|
||
- Provider URL:填写 Active MQ 的 URL,如:tcp://localhost:61616
|
||
- Use Authorization:勾选 Use Authorization 并填写 用户 和 密码
|
||
- Connection Factory:ConnectionFactory
|
||
- Destination
|
||
- 如果是 Topic,则为 `dynamicTopics/${TopicName}`,如 `dynamicTopics/topic.dev.info`
|
||
- 如果是 Queue,则为 `dynamicQueues/${QueueName}`,如 `dynamicQueues/topic.dev.info`
|
||
- 消息内容
|
||
```json
|
||
{
|
||
"dev_code": "${devCode}",
|
||
"dev_name": "DEV_NAME${num}",
|
||
"time": "${__time(yyyy-MM-dd HH:mm:ss.SSS,)}"
|
||
}
|
||
```
|
||
|
||
## 监听器
|
||
|
||
监听器可以对数据发送的数据进行统计,可以在该线程组下添加需要的监听器。 |