如何在JMeter的While控制器中发起异步HTTP(S)请求
解决JMeter动态数量异步HTTP请求的方案
针对你需要根据前置请求结果动态发起n个异步并行HTTP请求的需求,以下是几种可行的解决方案:
方案一:动态线程组实现并行
- 先通过前置HTTP请求获取n的值,将其存储到JMeter变量(比如
request_count)。 - 添加Dynamic Thread Group(需安装JMeter Plugins),在线程组配置中,将"Number of Threads"设置为
${request_count}。 - 在动态线程组内放置单个HTTP请求采样器,每个线程会独立执行一次该请求,所有请求会并行发起。
- 若每个请求需要不同参数(比如不同的ID),可通过
${__threadNum}关联线程编号,从前置请求的响应结果中提取对应参数(例如用__V函数引用param_${__threadNum}这样的变量)。 - 优点:请求隔离性好,JMeter原生支持线程级监控;缺点:线程创建有一定开销,n过大时可能影响JMeter性能。
- 若每个请求需要不同参数(比如不同的ID),可通过
方案二:JSR223 Sampler结合异步HTTP客户端
通过编写代码直接发起异步请求,灵活性更高:
- 前置请求获取n和所有请求的参数,将参数解析为列表(比如用JSR223 Sampler解析JSON响应,把参数存到
ArrayList类型的JMeter变量中)。 - 添加JSR223 Sampler,引入异步HTTP客户端(如OkHttp)编写代码循环发起请求:
import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Callback import okhttp3.Response import java.util.concurrent.CountDownLatch import java.io.IOException // 初始化客户端和计数器 def client = new OkHttpClient() def requestCount = vars.get("request_count") as int def latch = new CountDownLatch(requestCount) def paramsList = vars.getObject("paramsList") // 从变量获取参数列表 paramsList.each { param -> def request = new Request.Builder() .url("https://your-target-url?param=${param}") .build() // 异步发起请求 client.newCall(request).enqueue(new Callback() { @Override void onFailure(okhttp3.Call call, IOException e) { log.error("请求失败: ${e.message}") latch.countDown() } @Override void onResponse(okhttp3.Call call, Response response) throws IOException { def responseBody = response.body().string() log.info("请求响应: ${responseBody}") // 可将响应存储到变量或文件 vars.put("response_${param}", responseBody) latch.countDown() } }) } // 等待所有请求完成(可选,若无需等待可移除) latch.await()- 注意:需将OkHttp的jar包放到JMeter的
lib目录下,重启JMeter生效。 - 优点:线程开销小(复用客户端线程池),可自定义请求逻辑和响应处理;缺点:需要编写代码,对异常处理和结果收集的要求较高。
- 注意:需将OkHttp的jar包放到JMeter的
方案三:Loop Controller + Async HTTP Request Sampler
利用异步采样器实现非阻塞循环:
- 前置请求获取n的值,存储为
request_count。 - 添加Loop Controller,设置循环次数为
${request_count}。 - 在Loop内添加Async HTTP Request Sampler(需安装JMeter Plugins),该采样器会在后台异步发送请求,不会阻塞Loop的执行流程。Loop会快速完成n次循环,所有请求会并行发起。
- 若需要等待所有请求完成后再执行后续步骤,可添加Synchronizing Timer,设置"Number of Simultaneous Users to Group By"为
${request_count}。 - 优点:配置简单,无需编写大量代码;缺点:异步采样器的响应结果处理不如普通HTTP Sampler直观,需注意结果的存储和断言逻辑。
- 若需要等待所有请求完成后再执行后续步骤,可添加Synchronizing Timer,设置"Number of Simultaneous Users to Group By"为
为何Parallel Controller嵌套While无效?
bzm - Parallel Controller在JMeter启动阶段就会初始化所有嵌套的采样器实例,而While Controller是在运行时才动态循环执行采样器。这种设计导致Parallel Controller无法感知运行时动态生成的n个请求,因此无法实现动态并行。
内容的提问来源于stack exchange,提问作者Antonio Mangiacotti
相关产品推荐
相关产品推荐

