关于线程组
线程组定义了将针对您的服务器执行特定测试用例的用户池。在线程组 GUI 中,您可以控制模拟的用户数(线程数)、加速时间(启动所有线程所需的时间)、执行测试的次数,以及可选的启动并停止测试时间。
线程组是JMeter测试计划的核心组件之一,是整个测试计划的入口,所有的取样器和控制器必须放置在线程组下。
可以将线程组视为一个虚拟用户池,其中的线程可被理解为虚拟用户,多个线程即多个虚拟用户,它们同时执行相同的一批任务。
在这个虚拟用户池中,每个线程之间是相互隔离且互不影响的。每个线程的执行过程中,操作的变量不会对其他线程的变量值产生影响。
线程组可以定义用户的行为,包括设置线程数、循环次数、启动延迟等关键参数。可以通过配置这些参数来模拟现实中用户可能的操作。
线程组分为四类:
线程组
setUp线程组
tearDown线程组
开放模型线程组
线程组、setUp线程组、tearDown线程组控制面板中的元素基本一致:
名称、注释
在取样器错误后执行的动作
线程数
Ramp-Up时间
Same user on each iteration
延迟创建线程直到需要(只有线程组有)
调度器
开放模型线程组控制面板中的元素:
名称、注释
在取样器错误后执行的动作
调度计划
随机种子
执行优先级
JMeter中,不同类型的线程组有着不同的优先级。优先级关系可用表达式表示:setUp线程组 > 线程组 = 开放模型线程组 > tearDown线程组
。
这意味着在测试计划执行过程中,setUp线程组
将首先执行,其后是线程组
和开放模型线程组
,最后执行tearDown线程组
。
通常情况下,setUp线程组
用于在测试执行之前进行一些初始化工作,而tearDown线程组
用于测试执行结束后的清理工作。
示例Jmeter脚本
-
测试计划下添加tearDown线程组、线程组、setUp线程组、固定定时器(作用于测试计划下的所有取样器)
-
tearDown线程组排在最前,setUp线程组排在最后
-
固定定时器的线程延迟:
3000
-
tearDown线程组、线程组、setUp线程组下皆添加HTTP请求取样器。名称分别为:
tearDown线程组-HTTP请求
、线程组-HTTP请求
、setUp线程组-HTTP请求
-
HTTP请求取样器的请求地址皆为:
HTTP://127.0.0.1:5000/GetList/
-
HTTP请求取样器的请求方式皆为:
GET
运行结果
setUp 线程组-HTTP请求
取样器在2024-07-11 17:21:00 CST
时,发送了请求。
线程组-HTTP请求
取样器在2024-07-11 17:21:03 CST
时,发送了请求。
tearDown线程组-HTTP请求
取样器在2024-07-11 17:21:06 CST
时,发送了请求。
优先级正是:setUp线程组
> 线程组
= 开放模型线程组
> tearDown线程组
。
线程数
线程组中的线程数
即是同时运行的虚拟用户数量。可以配置线程数量来模拟多少用户同时访问目标应用程序或服务。
示例Jmeter脚本
-
测试计划下添加线程组、查看结果树
-
线程组面板中的线程数配置为:
3
-
线程组下添加HTTP请求取样器
-
取样器的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
取样器的请求方式:
GET
运行结果
结果中有3
个请求,Thread Name分别为线程组 1-1
、线程组 1-2
、线程组 1-3
。
这代表Jmeter启功了3个线程,1个线程就代表1个用户,可以说现在是3个用户一起执行线程组
。
循环次数
JMeter中,循环次数是指每个线程(用户)执行测试计划的次数。可以配置循环次数模拟用户访问目标应用程序或服务的次数。
示例Jmeter脚本
-
测试计划下添加线程组、查看结果树
-
线程组面板中的循环次数配置为:
3
-
线程组下添加HTTP请求取样器
-
取样器的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
取样器的请求方式:
GET
运行结果
结果中有3
个请求,Thread Name分别为线程组 1-1
、线程组 1-1
、线程组 1-1
。
这是因为线程(用户)循环执行了3次。
取样器错误后执行的动作
取样器(Sampler)是用于模拟用户请求发送到目标服务器的组件,例如HTTP请求、FTP请求等。当取样器执行过程中出现错误时,可以通过配置相应的动作来处理这些错误。以下是处理取样器错误时,线程组中常见方式:
-
继续
-
停止测试
-
立即停止测试
-
停止线程
-
启动下一进程循环
继续
线程组-取样器错误后执行的动作的默认选项,JMeter将在取样器执行错误时,忽略错误继续执行本线程的后续操作及执行其他线程。
停止测试&单线程组
任何一个取样器在执行过程中遇到错误时,整个测试计划将会在所有当前正在执行的线程执行完毕后停止。
取样器也有执行优先级,线程组下的取样器,从上到下顺序执行。
示例Jmeter脚本
-
测试计划下添加线程组、查看结果树
-
线程组面板中取样器错误后执行的动作配置为
停止测试
-
线程组下添加2个HTTP请求取样器,名称分别为
错误请求
、正确请求
-
错误请求排序在上,正确请求排序在下
-
错误请求的请求地址:
HTTP://127.0.0.1:5000/api/
-
正确请求的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
错误请求和正确请求的请求方式:
GET
运行结果
停止测试使Jmeter在错误请求
发生错误后,等待所有当前正在执行的线程执行完毕后停止测试计划。
正确请求
总会在错误请求
执行完毕后执行,所以错误发生时,正确请求
还没开始执行,此时Jemter已经停止测试计划了。
我们再仔细想一下,多线程及多循环时,它是怎么运作的。
Jmeter中,线程组配置多线程时,线程之间也有优先级,以线程组 1-1>线程组 1-2>线程组 1-3
类推。
当线程组 1-2
的某个取样器发生错误时,Jmeter不会执行线程组 1-3
。
多循环时,不用多说,大家都能明白优先级的情况。第二次循环,某个取样器发生错误时,Jmeter不会执行第三次循环。
停止测试&多线程组
任何一个取样器在执行过程中遇到错误时,整个测试计划将会在所有当前正在执行的线程执行完毕后停止。
不同线程组下的取样器,以线程组的优先级为准,例如线程组内的取样器执行优先级比tearDown线程组的高。
示例Jmeter脚本
-
测试计划下添加2个线程组,名称分别为:
线程组1
、线程组2
-
测试计划下添加查看结果树
-
测试计划面板中不勾选独立运行每个线程组
-
线程组1面板中取样器错误后执行的动作配置为
停止测试
-
线程组1下添加HTTP请求取样器,名称为:
错误请求
-
错误请求的请求地址:
HTTP://127.0.0.1:5000/api/
-
线程组1下添加2个HTTP请求取样器,名称分别为:
Sleeper接口请求
、GetList接口请求
-
Sleeper接口请求排序在前,GetList接口请求排序在后
-
Sleeper接口请求的请求地址:
HTTP://127.0.0.1:5000/Sleeper/
(接口中已设置延迟3秒响应) -
GetList接口请求的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
三个取样器的请求方式皆配置为:
GET
运行结果
第一道红线上的信息是错误请求-线程组1 1-1
发出请求的时间,为:2024-07-12 16:01:26,761
。
第二道红线上的信息是Sleeper接口请求-线程组2 2-1
发出请求的时间,为:2024-07-12 16:01:26,763
。
第三道红线上的信息是错误请求-线程组1-1
检测到了一个关闭测试的信号。
后面的信息就是等待Sleeper接口请求-线程组2 2-1
完成,然后关闭测试。
Sleeper接口请求
延迟3秒响应导致GetList接口请求
会在3秒后执行(执行优先级),所以错误请求
发生错误时,GetList接口请求
还未执行,那就不会执行GetList接口请求
了。
或许已经有读者在思考测试计划配置独立运行每个线程组
时,它应该如何运作。我直接给你答案罢。经过测试,它存在Bug,表现为排序在前的线程组中取样器发生错误,但后面的线程组仍有概率会执行。虽然我们的期望是后面的线程组必然不会执行。
立即停止测试
任何一个取样器在执行过程中遇到错误时,JMeter会立即停止当前运行的测试,不再执行任何后续的请求或操作。
单线程组中的取样器有严格的执行优先级,仅单线程组场景下,配置停止测试
与配置立即停止测试
的作用一致。我们就只探究多线程组场景下,它的作用。
需要注意,测试计划配置独立运行每个线程组
时,会出现与配置停止测试
一样的Bug。
示例Jmeter脚本
-
测试计划下添加2个线程组,名称分别为:
线程组1
、线程组2
-
测试计划下添加查看结果树
-
测试计划面板中不勾选独立运行每个线程组
-
线程组1面板中取样器错误后执行的动作配置为
立即停止测试
-
线程组1下添加HTTP请求取样器,名称为:
错误请求
-
错误请求的请求地址:
HTTP://127.0.0.1:5000/api/
-
线程组1下添加2个HTTP请求取样器,名称分别为:
Sleeper接口请求
、GetList接口请求
-
Sleeper接口请求排序在前,GetList接口请求排序在后
-
Sleeper接口请求的请求地址:
HTTP://127.0.0.1:5000/Sleeper/
(接口中已设置延迟3秒响应) -
GetList接口请求的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
三个取样器的请求方式皆配置为:
GET
运行结果
与配置停止测试
不同的是,第三道红线上的信息不再是关闭测试的信号,而是直接关闭测试。导致Sleeper接口请求
被强制关闭与服务器端的连接,红框中的响应体信息显示读取数据错误。
停止线程
任何一个线程(用户)在执行过程中遇到错误时,该线程被停止,不影响其他线程(用户)。
示例Jmeter脚本
-
测试计划下添加线程组、查看结果树、用户参数(右键-添加-前置处理器)
-
用户参数添加三个变量,名称分别为:
name
、name1
、lujing
-
用户参数添加三个用户(可用于参数化,1个线程引用一个用户变量)
用户_1的name变量值:
线程1的错误请求
用户_2的name变量值:
线程2的正确请求
用户_3的name变量值:
线程3的正确请求
用户_1的name1变量值:
线程1的
用户_2的name1变量值:
线程2的
用户_3的name1变量值:
线程3的
用户_1的lujing变量值:
/api/
用户_2的lujing变量值:
/GetList/
用户_3的lujing变量值:
/GetList/
-
线程组面板中取样器错误后执行的动作配置为:
停止线程
,线程数配置为:3
,循环次数配置为:2
-
线程组下添加2个HTTP请求取样器,名称分别为:
${name}
、${name1}GetList接口请求
-
${name}的请求地址:
HTTP://127.0.0.1:5000${lujing}
-
${name1}GetList接口请求的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
两个取样器的请求方式:
GET
运行结果
线程1的第1取样器-线程1的错误请求
发生错误后,线程1后续的取样器及循环不再执行。但不影响其他线程取样器的执行,线程2和线程3正常执行。
多线程组也是多线程,读者在实际的脚本编写中,需注意每个线程的情况去使用停止线程
。
启动下一进程循环
任何一个线程(用户)在执行过程中遇到错误时,Jmeter会立即停止当前线程的本次执行,并进行当前线程(用户)的下次执行,不影响其他线程,主要应用于线程多次循环时。
示例Jmeter脚本
-
测试计划下添加线程组、查看结果树、用户参数
-
用户参数添加三个变量,名称分别为:
name
、name1
、lujing
-
用户参数添加三个用户
用户_1的name变量值:
线程1的错误请求
用户_2的name变量值:
线程2的正确请求
用户_3的name变量值:
线程3的正确请求
用户_1的name1变量值:
线程1的
用户_2的name1变量值:
线程2的
用户_3的name1变量值:
线程3的
用户_1的lujing变量值:
/api/
用户_2的lujing变量值:
/GetList/
用户_3的lujing变量值:
/GetList/
-
线程组面板中取样器错误后执行的动作配置为:
启动下一进程循环
,线程数配置为:3
,循环次数配置为:2
-
线程组下添加2个HTTP请求取样器,名称分别为:
${name}
、${name1}GetList接口请求
-
${name}的请求地址:
HTTP://127.0.0.1:5000${lujing}
-
${name1}GetList接口请求的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
两个取样器的请求方式:
GET
运行结果
线程1的第1取样器-线程1的错误请求
发生错误后,线程1后续的取样器不再执行,但循环会继续-线程1的错误请求
执行第二次。也不影响其他线程取样器的执行,线程2和线程3正常执行。
ramp-up时间
ramp-up时间用于设置启动所有线程所需要的时间。例如:线程数设置为10,ramp-up时间设置为100秒,那么各线程启动间隔为10秒(100/10),即每个用户将在前一个用户启动后的10秒启动。
如果ramp-up值设置得很小、线程数又设置得很大,刚开始执行测试时会对服务器产生很大的压力。
示例Jmeter脚本
-
测试计划下添加线程组、查看结果树
-
线程组面板中Ramp-Up时间配置为:
9
,线程数配置为:3
-
线程组下添加HTTP请求取样器
-
HTTP请求取样器的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
HTTP请求取样器的请求方式:
GET
运行结果
各个线程的执行间隔正好是3秒(9/3)。
same user on each iteration(在每次迭代中使用相同的用户)
没有研究出来它有什么用。经过我的测试,same user on each iteration(在每次迭代中使用相同的用户)
启用与否,作用是一样的。
如读者有什么见解,欢迎谈论,共同探讨。目前,我十分费解。
延迟创建线程直到需要
启用延迟创建线程直到需要
时,JMeter会根据预设的Ramp-up时间
动态地分配线程。假设Ramp-up时间
设置为20秒,线程数
为10,那么JMeter会在测试启动后立即创建第一个线程并开始请求处理。随后,每隔2秒,JMeter将创建下一个线程,直到所有线程都被启动。
如果关闭延迟创建线程直到需要
选项,JMeter会在测试开始时一次性创建所有线程,然后间隔执行。即在测试一开始,JMeter会立即创建全部的10个线程,然后每个线程将间隔2秒启动。
这一配置的目的是为了应对测试机性能有限的情况。通过这种方式,可以避免在测试初期就创建所有线程,导致资源过度占用和可能的性能问题。这种方法有助于平滑地增加系统负载,同时防止资源瞬间紧张导致测试无法正常进行。
调度器
调度器主要控制线程操作时间,包含持续时间、启动延迟
两个参数。
持续时间(值不能为空)可以设置线程组的执行时间上限,达到上限后停止线程组的执行(已执行的不受影响)。
启动延迟可以为线程组的线程执行添加延迟时间。
持续时间,启动延迟同时有值时,启动延迟的时间计算到持续时间里。如启动延迟3秒
,持续时间20秒
,总执行时间为20秒
。
示例Jmeter脚本
-
测试计划下添加线程组、查看结果树
-
线程组面板中持续时间配置为
10
,启动延迟配置为:3
,循环次数配置为:永远
-
线程组下添加HTTP请求取样器、固定定时器
-
HTTP请求取样器的请求地址:
HTTP://127.0.0.1:5000/GetList/
-
HTTP请求取样器的请求方式:
GET
-
固定定时器的线程延迟配置为:
2000
(防止请求过多)
运行结果
红线第1行的All thread groups have been started
表示所有线程组都已经开始执行。再上面一行表示线程组1已开始执行。时间是2024-07-15 14:03:56,234
。
红线第2行的Thread started: 线程组 1-1
表示线程组1中的线程1-1已经开始。时间是2024-07-15 14:03:59,234
。
红线第三行的Notifying test listeners of end of test
表示测试结束,正在通知所有测试监听器。时间是2024-07-15 14:04:07,296
。
线程组1和线程组1中的线程1-1的执行间隔就是3秒
,再到结束测试的时间间隔为11秒左右
(持续时间存有误差)。
© 转载需要保留原始链接,未经明确许可,禁止商业使用。CC BY-NC-ND 4.0
...