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

如何在JMeter中使用并行/吞吐量控制器迭代多参数请求?

JMeter大参数列表迭代优化方案

问题背景

此前通过JSR223后置处理器生成三个参数列表,代码如下:

def imgUIDArrayList = vars.getObject("imageUIDListVal");
def fileListArrayList = vars.getObject("fileListVal");
def filePathListArrayList = vars.getObject("filePathListVal");

1.upto(imgUIDArrayList.size(),{ vars.put('imageUUIDA_' + it, imgUIDArrayList.get(it - 1))})
1.upto(fileListArrayList.size(), { vars.put('fileUUIDA_' + it, fileListArrayList.get(it - 1))})
1.upto(filePathListArrayList.size(), { vars.put('filePathUUIDA_' + it, filePathListArrayList.get(it - 1))})

使用ForEach控制器迭代调用API时,参数列表规模小(如10个)时正常,但规模超过100甚至1000时,单用户执行时长超30分钟,并发时耗时进一步增加,而实际API本身无此性能问题。

当前ForEach控制器配置:
ForEach控制器配置

控制器内通过以下方式调用另外两个变量:

  • ${__V(fileUUIDA_${__counter(,)})}
  • vars.get('filePathUUIDA_' + ((vars.get('__jm__ForEach Controller__idx') as int) + 1))

现需解决:如何用Parallel Controller或Throughput Controller实现对应次数的请求迭代?或是否有更优方案?


最优方案:JSR223采样器异步批量请求

ForEach控制器是串行迭代,每个请求必须等待上一个完成,这是性能瓶颈的核心原因。直接用JSR223采样器发起异步HTTP请求,能最大化利用API的并行处理能力,步骤如下:

  1. 添加JSR223采样器,选择Groovy语言
  2. 写入以下代码(替换你的API地址、请求方法、参数模板):
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils

// 直接获取原始列表,避免拆分变量的开销
def imgUIDs = vars.getObject("imageUIDListVal")
def fileUUIDs = vars.getObject("fileListVal")
def filePaths = vars.getObject("filePathListVal")

// 创建可复用的HTTP客户端
CloseableHttpClient client = HttpClients.createDefault()
def futures = []

// 异步遍历所有参数组合发起请求
imgUIDs.eachWithIndex { imgUID, index ->
    def fileUUID = fileUUIDs[index]
    def filePath = filePaths[index]
    
    // 构造请求(按需修改请求方法、头、体)
    HttpPost post = new HttpPost("你的目标API地址")
    post.setHeader("Content-Type", "application/json")
    def requestBody = """{"imageUID":"${imgUID}", "fileUUID":"${fileUUID}", "filePath":"${filePath}"}"""
    post.setEntity(new StringEntity(requestBody))
    
    // 异步执行并收集结果
    futures << client.executeAsync(post, { response ->
        def statusCode = response.getStatusLine().getStatusCode()
        log.info("请求完成,状态码: ${statusCode}")
        EntityUtils.consume(response.getEntity()) // 释放资源
    })
}

// 等待所有请求完成
futures.each { it.get() }
client.close()

该方案跳过JMeter控制器的串行调度开销,直接发起并行请求,性能可接近API本身的处理极限。


Parallel Controller实现方式

Parallel Controller可让内部请求并行执行,结合Loop Controller实现对应次数的迭代:

  1. 添加Parallel Controller
  2. 在Parallel Controller内添加Loop Controller,设置循环次数为参数列表长度(动态获取:${__groovy(vars.getObject("imageUIDListVal").size(),)})
  3. 在Loop Controller内添加API请求,参数调用方式:
    • 用计数器:${__V(imageUUIDA_${__counter(,)})}
    • 用Loop内置索引:vars.get('imageUUIDA_' + ((vars.get('__jm__Loop Controller__idx') as int) + 1))

注意:Parallel Controller的并行度受JMeter线程数限制,大列表场景需合理调整线程数,避免压垮目标API。


Throughput Controller实现方式

Throughput Controller主要用于控制请求执行的总次数或比例,仅适合需要限制迭代次数的场景,无法解决串行耗时问题:

  1. 添加Throughput Controller,选择「Total Executions」模式
  2. 设置吞吐量为参数列表长度(动态获取:${__groovy(vars.getObject("imageUIDListVal").size(),)})
  3. 在控制器内添加API请求,参数调用方式同Loop Controller

该方案仍为串行执行,仅适合不需要优化性能、仅需控制迭代次数的场景。


内容的提问来源于stack exchange,提问作者Jyoti Prakash Mallick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:07:34