JMeter并发线程组下如何在While控制器中实现异步调用等待
JMeter Concurrency Thread Group 异步等待逻辑实现方案
问题核心原因
Concurrency Thread Group 的单线程执行逻辑为串行执行其作用域内的所有组件,仅当当前线程的所有组件执行完成后才会触发下一次迭代。你将异步校验的 While 控制器和 POST 请求放在同一个线程执行流中,线程会被 While 控制器阻塞,无法持续发送新的 POST 请求,因此达不到预期并发效果。
可行实现方案
要拆分「发送请求」和「异步校验」两个逻辑,避免互相阻塞:
方案1:使用两个独立的 Concurrency Thread Group
- 第一个线程组仅负责发送 POST 请求,并发数设置为你需要的压测并发值,发送请求后将需要校验的业务标识(比如订单ID、流水号)写入 JMeter 属性 或者 本地文件队列 中
- 第二个线程组单独处理持久化校验逻辑,固定并发数(根据你的校验接口吞吐量设置即可),循环从属性/文件队列中读取业务标识,放到 While 控制器中执行校验逻辑
- 注意跨线程组传参不要用
vars变量,vars仅作用于当前线程,需要用props.put()/props.get()操作全局属性,或者用__setProperty()/__property()函数实现
方案2:同一线程组内使用 JSR223 组件异步提交校验任务
- 在 POST 请求执行完成后,添加 JSR223 采样器,将校验逻辑封装为异步任务提交到自定义的线程池执行,不需要等待返回结果,当前线程直接进入下一轮迭代发送新的 POST 请求
- 示例代码片段(放在 JSR223 采样器中,语言选 Groovy):
// 初始化线程池逻辑仅执行一次即可,建议放在 setUp 线程组中执行 // def pool = java.util.concurrent.Executors.newFixedThreadPool(10) // props.put("checkPool", pool) def pool = props.get("checkPool") def bizId = vars.get("你的业务标识变量名") // 提交异步校验任务 pool.submit({ // 此处写入你的校验逻辑,可直接调用校验接口、封装轮询规则 def isPersisted = false while(!isPersisted) { // 调用校验接口、判断持久化状态的逻辑,校验通过则修改isPersisted为true退出循环 sleep(1000) // 轮询间隔可根据业务需求调整 } } as Runnable)
- 测试结束后记得在 tearDown 线程组中调用
props.get("checkPool").shutdown()关闭线程池,避免资源泄漏
方案3:同一线程组内用吞吐量控制器控制请求速率
如果不想拆分线程组,可以调整 While 控制器的位置,把 While 控制器放到线程组的子级独立控制器中,用吞吐量控制器强制保证 POST 请求的发送速率不受校验逻辑阻塞,该方案控制精度略低于前两种方案。
已搭建测试计划参考

内容的提问来源于stack exchange,提问作者sman
相关产品推荐
相关产品推荐

