如何使用JMeter向特定运行线程发送邮件?If控制器运行异常
JMeter指定线程触发邮件发送不稳定的解决方案
问题根因
${__threadNum} 本身并不是线程的固定唯一标识,它返回的是当前时刻执行采样的工作线程临时编号,以下场景都会导致它的返回值不符合预期,直接放在If控制器做判断自然会偶发失效:
- 线程组内有线程执行完成提前退出,剩余线程调度时编号会重新映射
- 开启分布式压测时,每个压测节点独立从1开始计数线程号,多节点同编号线程会重复触发/漏触发
- If控制器没有开启变量表达式模式时,内嵌的函数会被多次解析,不同解析节点拿到的线程号不一致
- setUp/tearDown线程组和业务线程组是独立线程池,跨线程组取
${__threadNum}拿到的是当前线程池的编号,和目标线程组完全无关
稳定实现步骤
- 给每个线程绑定生命周期内不变的固定标识
在线程组下最靠前的位置添加JSR223 Sampler,语言选择Groovy,写入如下代码:// 生成当前线程全生命周期固定的唯一标识,不会随调度变化 def threadCustomId = ctx.getThread().getThreadName() vars.put("currentThreadId", threadCustomId) // 按需设置发信标记,比如指定第1个业务线程发信(注意JMeter原生线程编号从0开始计数) vars.put("needSendMail", ctx.getThreadNum() == 0 ? "true" : "false") - 调整If控制器判断逻辑
打开If控制器配置页,条件输入框直接填${needSendMail},同时勾选*Interpret Condition as Variable Expression?*选项,该模式下不会重复解析表达式,判断性能和稳定性远高于直接写函数判断。 - 邮件组件配置
将SMTP请求采样器放在If控制器内部,邮件的收件人、正文、触发场景参数全部提前通过JSR223脚本生成后存入JMeter变量,不要在SMTP采样器的配置项里嵌套调用线程相关函数,避免取值错位。
跨线程组触发的特殊处理
如果需要在业务线程运行到特定节点时,触发其他独立线程组发邮件,不要直接传递线程号判断,要通过JMeter全局属性传递触发标记:在业务线程满足发信条件时用
props.put("mailTrigger_"+ctx.getThread().getThreadName(), "true")写入标记,发信线程组轮询对应属性值判断是否触发即可。
内容的提问来源于stack exchange,提问作者Prasad Boj
相关产品推荐
相关产品推荐

