JMeter Constant Timer未在请求间生效,如何设置请求间延迟?
问题描述
我创建了一个简单测试计划,包含:
- 线程组(Thread Group)
- 执行GET请求的HTTP取样器(HTTP Sampler)
服务器会记录请求进入时间,我设置了3个线程(用户),循环次数为2。尝试在线程组层级和取样器层级添加**恒定定时器(Constant Timer)**后,观察日志发现定时器是在每次循环后添加延迟,而非文档说明的每次请求后。
我是否遗漏了什么?如何实现每次请求后添加延迟?使用的JMeter版本为5.6.2。
补充信息
- 日志样本
- 线程组截图
- 恒定定时器截图(设置延迟5000ms)
日志显示前3条请求在同一秒产生,后3条在5秒后,说明定时器在每次循环后生效,而非每次请求后。日志内容如下:
2024-02-22 22:29:31.724 INFO 19108 --- [http-nio-80-exec-1] : Entry, user=1 2024-02-22 22:29:31.724 INFO 19108 --- [http-nio-80-exec-4] : Entry, user=3 2024-02-22 22:29:31.724 INFO 19108 --- [http-nio-80-exec-3] : Entry, user=2 2024-02-22 22:29:36.771 INFO 19108 --- [http-nio-80-exec-6] : Entry, user=1 2024-02-22 22:29:36.771 INFO 19108 --- [http-nio-80-exec-2] : Entry, user=2 2024-02-22 22:29:36.771 INFO 19108 --- [http-nio-80-exec-5] : Entry, user=3
问题原因及解决方案
原因分析
JMeter的恒定定时器(Constant Timer)默认逻辑是在取样器执行之前添加延迟,而非执行之后。当定时器放在线程组层级时,它会作用于线程组下所有取样器,但执行时机为:线程启动后第一个取样器执行前,以及每次循环的第一个取样器执行前——这就导致了你看到的“循环后延迟”现象,本质是下一次循环的第一个请求前触发了延迟。
实现每次请求后延迟的方法
要实现每次请求之后添加延迟,推荐以下两种方式:
后置处理器添加延迟代码
给HTTP取样器添加一个JSR223 PostProcessor(推荐用Groovy语言,性能优于BeanShell),在脚本中写入延迟逻辑:// 延迟5000毫秒(5秒) Thread.sleep(5000);这个方法会在每次取样器执行完成后立即触发延迟,完全符合“每次请求后延迟”的需求。
调整定时器逻辑(备选)
如果坚持使用定时器,可结合循环控制器拆分请求逻辑,但这种方式复杂度更高。相比之下,后置处理器的sleep方法更直接高效。
另外,可检查线程组的「延迟线程创建直到需要」选项,确保未勾选——该选项可能导致线程集中启动,加剧第一批请求同时发出的情况,但这不是核心问题,核心仍在于定时器的执行时机。
内容的提问来源于stack exchange,提问作者granier

