JMeter中每10个线程执行后触发Loop-1请求的实现方案
JMeter实现每10个线程完成后触发指定请求的方案
核心思路
放弃依赖线程启动索引(__jm__Thread Group__idx),改用JMeter全局共享属性记录已完成的线程数量——因为线程是并发执行的,启动顺序和完成顺序往往不一致,索引无法准确反映实际完成计数。当全局计数达到10的整数倍时,触发目标请求。
具体实现步骤
1. 初始化全局计数器
在测试计划最顶部添加一个JSR223 Sampler(放在所有线程组之前),用来初始化全局计数变量:
// 初始化已完成线程数和触发次数 props.put('completedThreads', 0) props.put('triggeredTimes', 0)
props是JMeter的全局属性,所有线程共享,不会随线程结束重置。
2. 主线程组内添加完成计数逻辑
在主线程组的最后一个位置(所有业务请求之后)添加JSR223 PostProcessor,每次线程完成后更新全局计数:
// 获取当前已完成线程数,初始为0 def count = props.get('completedThreads') as int count++ props.put('completedThreads', count) // 检查是否达到10的倍数,设置触发标记 if (count % 10 == 0) { props.put('needTrigger', true) }
3. 配置触发请求的独立线程组
添加一个单独的线程组,配置如下:
- 线程数:1
- 循环次数:永久(或根据测试总线程数设置足够大的数值)
- 添加Constant Timer,设置间隔(比如100ms,避免频繁检查消耗资源)
在这个线程组内依次添加:
3.1 JSR223 Sampler(检查触发条件)
def needTrigger = props.get('needTrigger') ?: false def triggeredTimes = props.get('triggeredTimes') as int def completed = props.get('completedThreads') as int // 确保每10个线程只触发一次,避免重复执行 if (needTrigger && (triggeredTimes * 10 < completed)) { vars.put('executeLoop1', 'true') props.put('needTrigger', false) props.put('triggeredTimes', triggeredTimes + 1) } else { vars.put('executeLoop1', 'false') }
3.2 If Controller
条件设置为:${executeLoop1} == true
3.3 放入Loop-1请求
将需要触发的Loop-1请求放在If Controller下,这样每当全局完成线程数达到10的倍数时,该请求就会被执行一次。
简化方案(无需额外线程组)
如果Loop-1请求不需要独立线程执行,可以直接在主线程组内实现:
修改主线程组内的JSR223 PostProcessor代码:
def count = props.get('completedThreads') as int count++ props.put('completedThreads', count) // 仅让第10、20...个完成的线程触发请求 vars.put('executeLoop1', (count % 10 == 0) ? 'true' : 'false')
然后在主线程组最后添加If Controller(条件${executeLoop1} == true),并放入Loop-1请求。这种方式的触发请求会由第10、20...个完成的线程本身执行,适合请求无需独立上下文的场景。
原代码失效原因
你使用的__jm__Thread Group__idx是线程的启动序号(从0开始),仅代表线程在组内的排列顺序,和实际完成顺序无关。比如线程组有20个线程,idx=9的线程可能是第3个完成的,此时用(idx+1)%10 ==0判断会导致触发时机完全错误。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

