You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JMeter中发送负载元素数量可变的请求并最终达到指定平均值?

JMeter动态调整请求节点数实现目标平均值方案

前置说明

利用JMeter全局属性props做跨线程的统计数据共享,结合JSR223前置处理器的动态逻辑,实现运行过程中实时校正节点生成数量,最终收敛到目标平均值3。

步骤1:初始化全局统计变量

添加setUp线程组,线程数设为1,循环数设为1,内部添加JSR223 Sampler,写入以下初始化代码:

// 初始化总请求计数
props.put("total_requests", 0L)
// 初始化总节点计数
props.put("total_objects", 0L)
// 配置目标平均值
props.put("target_average", 3G)

步骤2:编写动态生成节点的JSR223 Preprocessor逻辑

替换你原有HTTP请求下的JSR223 Preprocessor代码为以下内容,可根据实际需求调整权重参数:

import java.util.Random
import java.math.BigDecimal

def random = new Random()
// 读取全局统计值
long totalReq = props.get("total_requests") as long
long totalObj = props.get("total_objects") as long
BigDecimal targetAvg = props.get("target_average") as BigDecimal
final int MIN_COUNT = 1
final int MAX_COUNT = 99

int currentCount
if (totalReq == 0) {
    // 首次请求直接生成1-3随机数
    currentCount = random.nextInt(3) + 1
} else {
    BigDecimal currentAvg = (totalObj / totalReq) as BigDecimal
    if (currentAvg > targetAvg) {
        // 当前平均偏高,生成小数值拉低平均
        currentCount = random.nextInt(2) + 1 // 1-2随机
    } else if (currentAvg < targetAvg) {
        // 当前平均偏低,70%概率生成3-8,30%概率生成8-99,兼顾随机性和收敛速度
        if (random.nextDouble() < 0.7) {
            currentCount = random.nextInt(6) + 3
        } else {
            currentCount = random.nextInt(92) + 8
        }
    } else {
        // 已达标,生成1-5随机数保持波动
        currentCount = random.nextInt(5) + 1
    }
}
// 边界校验,避免超出1-99范围
currentCount = Math.max(MIN_COUNT, Math.min(MAX_COUNT, currentCount))

// 生成对应数量的XML节点,可替换为你自己的节点生成逻辑
StringBuilder nodeBuilder = new StringBuilder()
for (int i = 1; i <= currentCount; i++) {
    String reqId = String.format("ID%05d", i)
    String docId = String.valueOf(100000000 + i)
    nodeBuilder.append("  <object a='false' b='false' pReqID='").append(reqId).append("'>\n")
    nodeBuilder.append("    <al ad='2021-09-20' alc='bla' bla='2021-09-20T11:00:00.000Z' sn='AB8912' />\n")
    nodeBuilder.append("    <doc docType='P' docId='").append(docId).append("' name='test' date='12/31/2022' />\n")
    nodeBuilder.append("  </object>\n")
}
// 存入变量替换HTTP请求中的占位符,比如你的请求里占位符是${object_nodes}
vars.put("object_nodes", nodeBuilder.toString())

// 线程安全更新全局统计值
synchronized (props) {
    props.put("total_requests", totalReq + 1)
    props.put("total_objects", totalObj + currentCount)
}

步骤3:运行结束结果校验

添加tearDown线程组,线程数设为1,循环数设为1,内部添加JSR223 Sampler,写入代码打印最终统计结果:

import java.math.BigDecimal

long totalReq = props.get("total_requests") as long
long totalObj = props.get("total_objects") as long
BigDecimal finalAvg = (totalObj / totalReq).setScale(2, BigDecimal.ROUND_HALF_UP)
log.info("===== 最终统计结果 =====")
log.info("总请求数:{}", totalReq)
log.info("总节点数:{}", totalObj)
log.info("平均节点数:{}", finalAvg)

运行结束后查看jmeter.log文件即可获取最终平均值,运行时长越长,结果越接近目标值3。

注意事项

  • 统计值必须存在全局属性props中,不要用单线程独有vars存储,避免多线程下统计异常
  • 可根据实际需求调整概率权重,比如需要更多高节点数的样本时,可提高偏低平均时大数值的生成概率
  • 高并发场景下synchronized锁仅作用于计数更新逻辑,性能损耗可忽略,不会影响压测结果

内容的提问来源于stack exchange,提问作者JustNatural

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 14:36:04