JMeter线程组模型是设计靠谱性能测试方案的基础,拆解原生和插件线程组,各种加压策略的配置方法从而估算并发用户数。
一、线程组的三个参数
打开任意线程组,看到的就是这三个参数定义了一条最简单的负载曲线:
线程数(Number of Threads):模拟的并发用户数上限。
Ramp-Up 时间(秒):在多少秒内将所有线程启动完毕。
循环次数(Loop Count):每个线程执行测试计划的次数。
启动速率 = 线程数 ÷ Ramp-Up 时间。如:线程数 100,Ramp-Up 60s,那么每秒启动约 1.67 个线程。当所有线程启动后,如果未设循环次数或调度器,每个线程跑完一次就退出。
绝对并发:Ramp-Up 设为 0,JMeter 会尝试瞬间启动所有线程,此时对施压机本身压力极大。
相对并发:Ramp-Up > 0,线程逐步启动,前一个线程开始执行后,后一个线程可能还没启动,所以在启动阶段并不是所有线程同时跑。
二、原生线程组
普通线程组(Thread Group)
最常用的线程组,适合简单的线性加压和不断负载。
配置:
线程数 – 最后并发数。
Ramp-Up – 达到最后并发所需时间。
循环次数 – 勾选“永远”或填具体数字。如果勾选永远,必须配合调度器设置不断时间,否则永不停止。
调度器(Scheduler) – 勾选后,可设置不断时间(秒)和启动延迟(秒)。此时循环次数一般设为永远,负载会跑满整个不断时间。
典型场景:100 并发,2 分钟内逐步加压完毕,然后维持 10 分钟稳定负载。配置:线程数 100,Ramp-Up 120,循环次数勾选永远,调度器不断时间 600(10分钟)。
注意:原生线程组无法实现阶梯加压并保持一段时间再继续增加的复杂曲线,只能做一次性线性爬坡。
setUp 线程组和 tearDown 线程组
setUp Thread Group:在普通线程组之前执行,用于准备测试数据、登录获取 Token 等预处理。
tearDown Thread Group:在普通线程组结束后执行,用于清理数据、登出等收尾操作。
配置参数和普通线程组完全一致,但执行时序特殊。如果脚本需要登录获取全局变量,必须把登录思路放到 setUp 组,并将 Token 通过 __setProperty 跨线程传递。
三、加压实现
瞬时加压用于秒杀场景
特点:在测试开始的瞬间将所有用户全部压上,模拟秒杀、抢购、整点开闸等零延迟高并发场景。
原生实现:将 Ramp-Up 设为 0,线程数填目的并发(如 500),循环次数一般设为 1,让所有线程同时启动并执行一次请求。如果需要更极端的集合点效果,可叠加同步定时器。
插件替代:也可以使用 Ultimate Thread Group 或 Concurrency Thread Group,将启动时间设为 0 秒来达到瞬间满负载。
注意事项:对施压机压力极大,单机线程数过高容易导致结果失真,建议配合分布式压测。
线性加压用于寻找性能拐点
特点:在较长一段时间内,均匀、不断地增加并发用户数,观察系统吞吐、响应时间随负载上升的变化趋势,从而找到性能短板拐点。
原生实现:设置一个较大的线程数(比如 200),Ramp-Up时间拉长(如 600 秒)。循环次数选永远,并配合调度器设置总不断时间(Ramp-Up 时间 + 平稳运行时间)。比如总时长 20 分钟,这样在 10 分钟内用户数从 0 线性爬升到 200,然后再保持 200 运行 10 分钟。
插件替代:Stepping Thread Group 或 Ultimate Thread Group也都能画出线性爬升曲线,但原生方式配置最简单。
阶梯加压
特点:分阶段增加并发用户数,每个阶段达到目的并发后保持一段时间,再增加下一批用户。这是最能反映真实业务水位变化的测试方式,比如先跑 50 并发看 3 分钟,再加到 100 并发看 3 分钟,依此类推。
原生实现:无法直接配置,需要借助插件。
标准插件:Stepping Thread Group(需通过 JMeter Plugins Manager 安装 jpgc - Standard Set)。可以精细控制初始线程数、每次增加的数量、增加间隔、爬坡时长以及最后保持时间,并且可以设置结束时的停止速率。用它来生成漂亮的阶梯状负载曲线非常方便。
突发尖峰
特点:在系统运行在低水位时,某个时间点瞬间涌入大量并发用户,不断一小段时间后又回到低水位,用来测试系统抗脉冲和弹性伸缩能力。
原生实现:无法直接做出低负载-瞬间高峰-低负载的曲线。
推荐插件:Ultimate Thread Group。通过设置一条短时大量线程的调度行,并给它一个较晚的启动延时,叠加在一个长期低负载行之上,就能在某个时刻制造出明显的尖峰。
波动负载
特点:并发用户数随时间像波浪一样起伏,模拟早晚高峰、整点活动等有规律波动的真实线上流量。
原生无法实现。
推荐插件:Ultimate Thread Group。你可以在界面中添加多个线程调度行,每一行都有各自的启动延时、爬坡时间、保持时间和关闭时间,多条曲线叠加在一起就能组合出任意波动形状,图形界面会实时预览。
不断负载
特点:将并发数固定在一个目的值,长时间施压,证实系统是不是存在内存泄漏、连接池不释放等长期运行稳定性问题。
原生实现:普通线程组加调度器,将线程数设为目的并发,Ramp-Up 可适当设置,循环次数勾选永远,并填写需要的不断时间。
插件增强:Concurrency Thread Group 专门为维持目的并发水平而设计,它会在线程因报错或结束而减少时自动启动新线程来补足,保证并发数始终围绕目的值,不受具体业务请求耗时影响,非常稳定。
四、并发用户数估算
经典公式
并发用户数 = (PV × 0.8) / (每天秒数 × 0.2) × (响应时间 + 思考时间)
其中,(PV × 0.8) / (86400 × 0.2) 代表 20% 时间内产生 80% 流量的峰值 QPS。再乘以(响应时间 + 思考时间)即可得到需要同时在线交互的用户数。
在线用户不等于并发用户
在线用户很多只是挂着,不发请求。只有正在执行操作的用户才是并发用户。必须加上合理的思考时间(固定定时器、高斯随机定时器),模拟真实停顿。
吞吐量和并发数关系
如果已知目的 TPS,且平均响应时间为 T,则:
并发用户数约等于 TPS × T
五、注意
一台施压机线程数别超 500~1000。JMeter 一个线程占用较多内存,默认 JVM 堆可能不够。必要时进行分布式压测,或调整 HEAP 参数(-Xms4g -Xmx4g)。
Ramp-Up 不要过短导致 Client 端短板。瞬时启动大量线程,JMeter 自身可能丢包或延迟异常,得到的曲线无意义。宁可增加施压机数量,也建议用阶梯爬坡。
参数化让每个用户不一样。使用 CSV Data Set Config 为每个线程提供独立的用户名、Token 等。避免所有线程用同一账号登录被服务器缓存或限流。
定时器:固定定时器模拟固定思考时间;高斯随机定时器更接近人类思考的随机波动;同步定时器制造集合点,模拟极端并发(注意,只能在单机生效,分布式需配合使用)。
不断负载必须加调度器。如果循环次数选永远且不加不断时间限制,测试将永不停止。请必须在调度器中填写不断时间。
结果观察方面:线程组只管压力,分析要结合监听器:Active Threads Over Time(活跃线程数)、Transactions per Second、Response Times Over Time。配合 jp@gc 系列监听器可以实时看到负载模型是不是符合预期。
简单的固定 N 并发跑 M 分钟 - 普通线程组加调度器。
需要阶梯爬坡观察拐点 - Stepping Thread Group。
模拟复杂波动的业务高峰 - Ultimate Thread Group。
需要精确控制并发数,不受采样器耗时影响 - Concurrency Thread Group。