jmeter 中的负载测试正在使用多个线程生成重复的连续 ID

问题描述 投票:0回答:1

场景

我正在使用其 API 的三个请求在系统中创建一些记录。在第一个请求中,我需要发送 ID,出于测试和跟踪目的,我使用采样器中生成的连续号码。

我需要测试系统在高负载下的行为,因此我从每秒 16 个线程开始,并将循环设置为 3000,运行大约 50 分钟以监视行为。

我预计运行大约 50 分钟并创建 48000 条记录。

发生什么事了?

运行后,我开始观察第一个请求中的一些错误,这些错误与 ID 重复有关。一些请求被拒绝,因为 Id 已存在。这是正确的行为,但我没想到会生成重复的 Id。

是如何做到的? 整体结构是这样的。请考虑灰色的项目已被禁用。

enter image description here

SetUp Thread Group 有一个 Sampler 来初始化 ID 计数器。我使用一个文件来存储上次使用的 Id,该采样器会验证该文件是否存在,并使用初始值相应地创建它。

所有采样器代码均为 Java、BeanShell 2.0b6 和 BeanShell Engine 1.0。

import java.io.*;
import java.util.concurrent.locks.ReentrantLock;

// Define the file path for the counter
File counterFile = new File("/Users/rickersilva/Documents/Zenus2Testing/prelive-counter.txt");
ReentrantLock lock = new ReentrantLock();

lock.lock();
try {
    // Check if the counter file exists
    if (!counterFile.exists()) {
        // If not, create it and set the initial value
        BufferedWriter writer = new BufferedWriter(new FileWriter(counterFile));
        writer.write("90000000"); // Initial value
        writer.close();
        log.info("DEV_LOG: Counter initialized with value 90000000");
    } else {
        log.info("DEV_LOG: Counter file already exists, skipping initialization.");
    }
} catch (IOException e) {
    log.error("DEV_LOG: Error initializing counter: " + e);
} finally {
    lock.unlock();
}

设置完毕后,我设置了一些与本例无关的用户定义变量、标题等。在“创建人员”请求中,我有 DNI 增量预处理器。其目的是提供一种安全的方式来访问文件、读取 ID、递增 ID 并将其保存回文件。我使用锁来防止线程同时打开它,希望在创建人员请求中不要使用相同的 Id。这显然不起作用,这是代码。

import java.io.*;
import java.util.concurrent.locks.ReentrantLock;

ReentrantLock lock = new ReentrantLock();
File counterFile = new File("/Users/rickersilva/Documents/Zenus2Testing/prelive-counter.txt");
int currentDni;
int nextDni;
String idNumber;

lock.lock();
try {
    // Read the current value of personDni from the file
    BufferedReader reader = new BufferedReader(new FileReader(counterFile));
    currentDni = Integer.parseInt(reader.readLine().trim());
    reader.close();
    
    // Increment the personDni and update the file
    nextDni = currentDni + 1;
    BufferedWriter writer = new BufferedWriter(new FileWriter(counterFile, false));
    writer.write(Integer.toString(nextDni));
    writer.close();
    
    // Set the personDni variable in JMeter
    idNumber = "16" + Integer.toString(nextDni);
    vars.put("idNumber", idNumber);
} catch (Exception e) {
    log.error("DEV_LOG: Error processing personDni: " + e);
} finally {
    lock.unlock();
}

提取器捕获 API 返回的 personId 以在下一个请求中使用。

我不明白为什么这会失败。在这种情况下,我对锁定的理解很可能不好。但我想不出其他方法来实现这一点。感谢您的时间和帮助。

load-testing java.util.concurrent jmeter-5.0 beanshell
1个回答
0
投票

看来您正在尝试实现关键部分控制器,请查看其源代码以了解应该如何完成。

我不认为你正在走向正确的方向,因为在你的情况下,你不会有超过 1 个虚拟用户执行这个块。因此,使用 JMeter 的内置 Counter 配置元素

更有意义

另外,我建议重新考虑使用 Beanshell,从 JMeter 3.1 开始,您应该使用 JSR223 测试元素和 Groovy 语言 进行脚本编写。

© www.soinside.com 2019 - 2024. All rights reserved.