Concurrency Thread Group与Stepping Thread Group的区别
这两种 JMeter 线程组(由 jmeter-plugins
提供,非核心 JMeter 自带)都是为了满足特定负载模式测试需求而设计的,但它们实现的机制和目标负载曲线有着显著的区别:
🛠 核心差异概览
特性 | Concurrency Thread Group (并发电线程组) | Stepping Thread Group (阶梯式线程组) |
---|---|---|
主要目标 | 维持指定的 当前并发用户数(活跃线程数)或 RPS 稳定。 | 以阶梯方式 逐步线性增加 用户(线程)数量。 |
负载曲线 | 目标稳定值(平台期):启动、到达目标、保持目标、结束。 |
阶梯上升 📈: 逐步增加线程数并在每个阶梯短暂维持。 ! |
控制方式 | 反馈机制(PID控制器)🔥:智能调整线程数以达到目标(并发或RPS)。 | 固定时序配置:严格按照用户设定的时间表逐步增加线程。 |
配置参数重点 | Target Concurrency (目标并发), Ramp Up Time (启动时间), Hold Target Rate Time (保持负载时间), Target Level (目标类型: 并发或RPS) |
This group will start , Start users count , Initial delay, seconds , Start users count , Increment users count , in every seconds, using ramp-up seconds, Then hold load for seconds. |
使用场景 | 稳定性测试、容量规划(恒定负载)、监控系统在特定并发/RPS下的行为(如响应时间、错误率)。 | 压力测试(逐步加压发现瓶颈)、冒烟测试(验证逐步增加用户是否出错)、性能摸底测试。 |
自动增减线程 | 是:当目标未达到时启动更多线程🔥;当目标超过时停止部分线程。 | 否:仅根据时间表启动新增用户,不会减少线程(直到测试结束)。 |
负载精准度 | 对于维持目标负载非常精确(依赖控制器性能)。🚀 | 负载线性上升,但每个阶梯负载的维持时间很短。 |
易用性 | 配置时需要理解并发/RPS目标以及控制器参数(如启动 RPS)。 | 配置更直观,计划性强(用户数和时间一目了然)。 |
🧠 深入原理剖析
- Concurrency Thread Group (并发线程组) -
kg.apc.jmeter.threads.ConcurrencyThreadGroup
- 目标驱动:它的核心目标是维持一个恒定的活跃用户数量(并发请求数)或达到恒定的每秒请求数 (RPS)。
- 反馈机制:内部采用类似 PID 控制器的算法。
- 它持续监控当前的并发数或实际的 RPS。
- 将监控值与用户设置的目标值(
Target Concurrency
/Target Throughput
) 进行比较。 - 根据比较的结果(偏差),动态调整活跃线程的数量。
- 如果当前并发/RPS 低于目标,它会尝试启动更多线程(如果还有可用线程)。
- 如果当前并发/RPS 高于目标,它会让一部分正在启动期的线程停止(暂停启动新用户)或在适当时候停止部分活跃线程(非强制中断执行中 Sampler)。
- 负载剖面:
- 启动(
Ramp-Up Time
):在设定的Ramp-Up Time
内,将并发数/负载提升到目标水平。控制器在调整线程启动速率时会努力平滑上升曲线。 - 平台期(
Hold Target Rate Time
) 🧊: 在设定的时间内,控制器会努力精确维持在目标并发数或 RPS 上(曲线为一个稳定的平台)。 - 结束(
Ramp-Down Time
- 可选): 如果设置了下降时间,会将负载平滑降低(通过停止线程)。
- 启动(
- 优点:对于需要长时间保持稳定、精确负载的场景非常强大。
- 缺点:配置和理解相对复杂一些,特别是当依赖 RPS 目标时。
- Stepping Thread Group (阶梯线程组) -
kg.apc.jmeter.threads.SteppingThreadGroup
- 时间表驱动:它的工作方式是通过一系列预定义的时间步骤来按计划逐步增加并发用户数量(线程数)。
- 阶梯式负载:用户配置一系列“阶梯(Step)”:
Start users count
(起始用户数): 初始创建的线程数。Initial delay, seconds
(初始延迟): 首次启动前的等待时间。Start users count
/Increment users count
(每次递增用户数) : 每次要增加的线程数。in every
seconds /using ramp-up
seconds (间隔时间/上升时间): 每隔多久增加一次用户,以及每次增加这些用户时所用的上升时间(用于平滑增加)。Then hold load for
seconds (在该阶维持时间)🧊: 在每次增加用户后,在该用户级别上短暂维持的时间(即阶梯的水平部分)。
- 负载剖面:
- 整个负载曲线呈现为多个上升斜坡 + 短暂水平平台组合的阶梯状。
- 每次到达一个新的阶梯平台后,只会维持用户设定的短暂时间(
hold load for
),然后立即进入下一个增加阶段。 - 一旦完成最后一步的增加和维持,测试结束(或进入下一个线程组)。
- 优点:配置直观易懂,非常适合逐步加压的过程,清晰地展示了系统在不同用户负载下性能表现(如响应时间增长点)。
- 缺点:在阶梯平台期维持的时间很短📉,无法长时间保持稳定的压力,不适合长时间稳定压力测试(如稳定性、浸泡测试)。
🧪 典型应用场景
- 选用 Concurrency Thread Group:
- 你需要测试系统在稳定并发或稳定 RPS下的表现长达数小时或数天(稳定性测试/Soak Test)。
- 你想知道在特定用户数(如 1000 并发用户)或者特定吞吐量(如 500 RPS)下,系统的响应时间、错误率是否符合要求。
- 你想模拟用户上线率下降后(使用 Ramp-Down),系统的行为。
- 核心问题:系统能否在预期负载上长时间稳定运行?
- 选用 Stepping Thread Group:
- 你想发现系统的性能瓶颈点📉(如响应时间开始陡增,或错误率突增的点在多少用户时出现)。
- 你需要一个清晰可见的负载增长过程,以便观察系统性能随负载变化的轨迹。
- 你想做个快速的“冒烟测试”,逐步增加用户看系统是否会在低负载下就出错。
- 你想测试系统能否逐步扩展到某个用户规模(容量规划探索)。
- 核心问题:系统在逐渐增加的用户负载下表现如何?它的拐点在哪里?
📌 总结关键区别
- 目标是稳定 vs 目标是增加:并发目标是维持一个恒定量(并发或RPS),线程组提供自动调节;阶梯目标是按时间表逐步提升线程量。
- PID反馈控制 vs 固定时间表:并发使用智能控制器动态调节线程数;阶梯严格按照配置的时间点增加固定数量的线程。
- 负载曲线形状不同:并发是 启动后稳定平台;阶梯是 多次上升+短暂平台。
- 适用场景不同:
- Concurrency 👉 稳定性测试、恒定压力基准测试。
- Stepping 👉 压力测试找瓶颈、阶梯加压摸底测试。
🏁 最终建议
- 在规划测试前 明确测试目的。需要系统在一个固定负载下长时间运行的稳定表现?选 Concurrency Thread Group。需要观察系统在不断增加负载下的行为直到崩溃点?选 Stepping Thread Group。
- 很多性能测试项目中,会同时使用或分阶段使用两种线程组:
- 先用 Stepping 快速加压找到大概的性能拐点和瓶颈。
- 在瓶颈点前选择一个负载水平(比如拐点用户数的 80%)。
- 用 Concurrency 在选定的负载水平上进行长时间的稳定性/容量测试。
理解这两种线程组的工作原理和区别,能够帮助你更有效地设计 JMeter 性能测试场景,获取更符合实际需求的性能数据。💪🏻