我们提供安全,免费的手游软件下载!

安卓手机游戏下载_安卓手机软件下载_安卓手机应用免费下载-先锋下载

当前位置: 主页 > 软件教程 > 软件教程

Jmeter-线程组下篇

来源:网络 更新时间:2024-05-08 15:30:34

线程组

线程组作为JMeter测试计划的核心组件之一,对于模拟并发用户的行为至关重要。线程组元件是整个测试计划的入口,所有的取样器和控制器必须放置在线程组下。

可以将线程组视为一个虚拟用户池,其中每个线程可被理解为一个虚拟用户,多个虚拟用户同时执行相同的一批任务。

在这个虚拟用户池中,每个线程之间是相互隔离且互不影响的。每个线程的执行过程中,操作的变量不会对其他线程的变量值产生影响。

线程组的关键任务之一是定义并发用户的行为,包括设置线程数、循环次数、启动延迟等关键参数。通过适当配置线程组,测试人员可以模拟多用户在系统中同时执行任务的场景,从而评估系统的性能和稳定性。

通过灵活使用setup线程组、线程组、tearDown线程组、开放模型线程组,配置前置操作、主要操作、后置操作,更能真实、详细的评估系统。

线程组分为四类:

  • 线程组
  • setUp线程组
  • tearDown线程组
  • 开放模型线程组

线程组、setUp线程组、tearDown线程组控制面板中的元素基本一致:

  • 名称、注释
  • 在取样器错误后执行的动作
  • 线程数
  • Ramp-Up时间
  • Same user on each iteration
  • 延迟创建线程直到需要(只有线程组有)
  • 调度器

开放模型线程组控制面板中的元素:

  • 名称、注释
  • 在取样器错误后执行的动作
  • 调度计划
  • 随机种子

取样器错误后执行的动作


在JMeter中,取样器(Sampler)是用于模拟用户请求发送到目标服务器的组件,例如HTTP请求、FTP请求等。当取样器执行过程中出现错误时,可以通过配置相应的动作来处理这些错误。以下是一些处理取样器错误时,线程组中常见方式:

  • 停止线程

    任何一个线程(用户)在执行过程中遇到错误时,该线程被停止,不影响其他线程(用户)。

  • 启动下一进程循环
    任何一个线程(用户)在执行过程中遇到错误时,Jmeter会立即停止当前线程的本次执行,并进行当前线程(用户)的下次执行,主要应用于线程多次循环时。

  • 继续(无需演示)

    JMeter将在取样器执行错误时,忽略错误继续执行本线程的后续操作及执行其他线程。


停止线程-多线程


示例接口代码

@ThreadGroup.route('/api/ThreadGroup5/', methods=['GET', 'POST'])  
def threadgroup5():  
    return '200'

示例Jmeter脚本

  • 测试计划 下添加 线程组

    取样器错误后执行的动作 中勾选 停止线程

    线程数 3

  • 线程组 下依次添加2个 HTTP 请求 取样器

    名称: 错误请求-${yonghu} (在前)、 正确请求-${yonghu}

    请求地址: HTTP://127.0.0.1:5000/api/ThreadGroup5/

    请求方式: GET

  • 线程组 下添加 CSV 数据文件设置 (右键-添加-配置元件)

    文件名 ceshi.txt的路径

    ceshi.txt文件内容:(复制后,手动删除前面的空格)
    200,用户1
    1111,用户2
    200,用户3

    文件编码 UTF-8

    变量名称 ceshi,yonghu

  • 错误请求 取样器下添加 响应断言

    值: ${ceshi}

  • 测试计划 中,添加 查看结果树

运行结果

连续运行了3次,结果是一致的。总共有三个用户执行线程组,其中 用户1 用户3 完全执行成功; 用户2 只执行了 错误请求

因为设置 取样器错误后执行的动作 停止线程 用户2 执行 错误请求 时发生错误,Jmeter只会停止 用户2 的后续执行,不会影响其他线程。

多线程组也是多线程,读者在实际的脚本编写中,要注意每个线程的情况去使用 停止线程


停止线程-多循环


示例接口代码

@ThreadGroup.route('/api/ThreadGroup5/', methods=['GET', 'POST'])  
def threadgroup5():  
    return '200'

示例Jmeter脚本

  • 测试计划 下添加 线程组

    取样器错误后执行的动作 中勾选 停止线程

    循环次数 3

  • 线程组 下依次添加2个 HTTP 请求 取样器

    名称: 错误请求-${xunhuan} (在前)、 正确请求-${xunhuan}

    请求地址: HTTP://127.0.0.1:5000/api/ThreadGroup5/

    请求方式: GET

  • 线程组 下添加 CSV 数据文件设置 (右键-添加-配置元件)

    文件名 ceshi.txt的路径

    ceshi.txt文件内容:(复制后,手动删除前面的空格)
    200,第1次循环
    1111,第2次循环
    200,第3次循环

    文件编码 UTF-8

    变量名称 ceshi,xunhuan

  • 错误请求 取样器下添加 响应断言

    值: ${ceshi}

  • 测试计划 中,添加 查看结果树

运行结果

连续运行了3次,结果是一致的。用户在第2次循环执行到 错误请求 时,Jmeter停止测试。

因为设置 取样器错误后执行的动作 停止线程 ,用户的第2次循环,执行 错误请求 时发生错误,Jmeter停止用户的后续执行(就它一个线程)。


启动下一进程循环


示例接口代码

@ThreadGroup.route('/api/ThreadGroup5/', methods=['GET', 'POST'])  
def threadgroup5():  
    return '200'

示例Jmeter脚本

  • 测试计划 下添加 线程组

    取样器错误后执行的动作 中勾选 启动下一线程循环

    循环次数 3

  • 线程组 下依次添加2个 HTTP 请求 取样器

    名称: 错误请求-${xunhuan} (在前)、 正确请求-${xunhuan}

    请求地址: HTTP://127.0.0.1:5000/api/ThreadGroup5/

    请求方式: GET

  • 线程组 下添加 CSV 数据文件设置 (右键-添加-配置元件)

    文件名 ceshi.txt的路径

    ceshi.txt文件内容:(复制后,手动删除前面的空格)
    200,第1次循环
    1111,第2次循环
    200,第3次循环

    文件编码 UTF-8

    变量名称 ceshi,xunhuan

  • 错误请求 取样器下添加 响应断言

    值: ${ceshi}

  • 测试计划 中,添加 查看结果树

运行结果

连续运行了3次,结果是一致的。用户执行了3次循环,其中第2次循环中, 错误请求 出现错误,跳过 正确请求

因为设置 取样器错误后执行的动作 启动下一线程循环 ,用户的第2次循环,执行 错误请求 时发生错误,Jmeter会跳过用户的本次执行,进行用户的后续执行。


ramp-up时间


ramp-up时间用于设置启动所有线程所需要的时间。例如:线程数设置为10,ramp-up时间设置为100秒,那么JMeter将使用100秒使10个用户启动并运行,即每个用户将在前一个用户启动后的10秒启动。

如果ramp-up值设置得很小、线程数又设置得很大,刚开始执行测试时会对服务器产生很大的压力。

示例接口代码

@ThreadGroup.route('/api/ThreadGroup5/', methods=['GET', 'POST'])  
def threadgroup5():  
    return '200'

示例Jmeter脚本

  • 测试计划 下添加 线程组

    Ramp-Up时间 :9

    线程数 3

  • 线程组 下添加1个 HTTP 请求 取样器

    请求地址: HTTP://127.0.0.1:5000/api/ThreadGroup5/

    请求方式: GET

  • 测试计划 中,添加 查看结果树

运行结果

连续运行了3次,结果是一致的。 3 个用户执行 线程组 ,各个用户的请求时间分别为 2024-04-15 16:12:37 CST 2024-04-15 16:12:40 CST 2024-04-15 16:12:43 CST

3 个用户执行请求的间隔时间正好是 3 秒,即 ramp-up时间/线程数


same user on each iteration(在每次迭代中使用相同的用户)


没有研究出来它有什么用。经过我的测试, same user on each iteration(在每次迭代中使用相同的用户) 启用与否,作用是一样的。

如读者对此有不同见解,欢迎与我联系,共同探讨。目前,我十分费解。


延迟创建线程直到需要


当在JMeter中启用 延迟创建线程直到需要 时,JMeter会根据预设的 Ramp-up时间 动态地分配线程。假设 Ramp-up时间 设置为20秒, 线程数 为10,那么JMeter会在测试启动后立即创建第一个线程并开始请求处理。随后,每隔2秒,JMeter将创建下一个线程,直到所有线程都被启动。

如果关闭“延迟创建线程直到需要”选项,JMeter会在测试开始时一次性创建所有线程。使用同样的参数,即在测试一开始,JMeter会立即创建全部的10个线程。这些线程会按照设定的“Ramp-up时间”进行执行,每个线程将间隔2秒启动。

延迟创建线程直到需要 这一配置的目的是为了应对测试机性能有限的情况。通过这种方式,可以避免在测试初期就创建所有线程,导致资源过度占用和可能的性能问题。这种方法有助于平滑地增加系统负载,同时防止资源瞬间紧张导致测试无法正常进行。


调度器-启动延迟


调度器 主要控制线程操作时间。启用 调度器 后,可以输入 持续时间 (值不能为空), 启动延迟 来控制线程组的操作时间及线程组操作前的延迟时间。

同时输入 持续时间 启动延迟 时,先计算 启动延迟 ,再计算 持续时间

示例接口代码

@ThreadGroup.route('/api/ThreadGroup5/', methods=['GET', 'POST'])  
def threadgroup5():  
    return '200'

示例Jmeter脚本

  • 测试计划 下添加 线程组

    启用 调度器

    持续时间 :10

    启动延迟 3

  • 线程组 下添加1个 HTTP 请求 取样器

    请求地址: HTTP://127.0.0.1:5000/api/ThreadGroup5/

    请求方式: GET

  • 测试计划 中,添加 查看结果树

运行结果

注意看图中右上角-黄色三角形左边的 计时器 ,值固定在 2 秒。这个计时器计算整个测试计划的持续时间。由于示例请求的接口响应较快,可以理解为计时器的时间就是 HTTP请求 时的时间。

因为 启动延迟 设置为 3 秒,所以 HTTP请求 会在延迟 3 秒执行。不过计时器的时间是 2 秒,误差 1 秒。我多次试过把 持续时间 启动延迟 的时间拉长,误差还是 1 秒。


调度器-持续时间


调度器 主要控制线程操作时间。启用 调度器 后,可以输入 持续时间 (值不能为空), 启动延迟 来控制线程组的操作时间及线程组操作前的延迟时间。

同时输入 持续时间 启动延迟 时,先计算 启动延迟 ,再计算 持续时间

示例接口代码

@ThreadGroup.route('/api/ThreadGroup6/', methods=['GET', 'POST'])  
def threadgroup6():  
    sleep(3)  
    return '200'

示例Jmeter脚本

  • 测试计划 下添加 线程组

    启用 调度器

    持续时间 :2

  • 线程组 下添加1个 HTTP 请求 取样器

    请求地址: HTTP://127.0.0.1:5000/api/ThreadGroup6/

    请求方式: GET

  • HTTP 请求 下添加1个 固定定时器

    值: 3000

  • 测试计划 中,添加 查看结果树

运行结果

图中结果树中什么都没有,这是因为线程组的 持续时间 只有 2 秒,但 固定定时器 的延迟有 3 秒,导致还未执行 取样器 ,持续时间已经结束。

此时删掉固定定时器,运行结果

此时有人会有疑问。接口中设置的 休眠时间 就已经是 3 秒了,脚本中的 持续时间 还只是 2 秒,为什么这次成功执行了呢?

持续时间 的设置,只作用于还未执行的取样器。已经执行的取样器,无论等待多长时间,都会执行完成。


本文示例接口源代码可从前言中下载。