JMeter 执行流程

JMeter 执行流程源码解析(基于 JMeter 5.1)

本文基于 JMeter 5.1 源码,梳理其整体执行流程,涵盖从初始化到线程组生命周期、采样器/控制器的执行顺序,再到结果收集与汇报的完整过程,帮助理解 JMeter 内部架构与实现原理。


1. 初始化阶段

JMeter 的启动与测试计划初始化主要涉及以下步骤:

  1. 启动入口

    • 启动类为 org.apache.jmeter.NewDriver,负责加载环境配置、类路径与插件。
    • 随后进入 org.apache.jmeter.JMeter 类的 start() 方法。
  2. 测试计划加载

    • 通过 SaveService.loadTree(FileInputStream) 加载 .jmx 脚本,解析为 HashTree 结构。
    • HashTree 是 JMeter 的核心数据结构,树状存储测试元素(TestElement),如线程组、控制器、采样器、监听器。
  3. 初始化组件

    • 每个节点实现了 TestElement 接口,初始化时会调用其 setRunningVersion(true)recoverRunningVersion()
    • 测试元素通过 BeanShell、GUI 配置或 TestBean 方式进行属性注入。
  4. 监听器与结果收集器注册

    • 结果收集器(ResultCollector)在此阶段注册到运行环境,用于后续数据汇报。

用户 NewDriver JMeter SaveService 测试计划树 启动 JMeter 调用 start() loadTree(jmx) 返回 HashTree 初始化 TestElement 用户 NewDriver JMeter SaveService 测试计划树


2. 线程组执行生命周期

线程组是 JMeter 测试执行的核心。源码关键类是 org.apache.jmeter.threads.ThreadGrouporg.apache.jmeter.threads.JMeterThread

  1. 线程组启动

    • 调用 ThreadGroup.start() 创建多个 JMeterThread 实例。
    • 每个线程对应一条独立的执行路径。
  2. JMeterThread 执行流程

    • 主方法在 JMeterThread.run()

      • 调用 threadStarted() 回调(实现了 ThreadListener 的组件会执行初始化逻辑)。
      • 进入循环,依次执行控制器与采样器。
      • 执行结束后调用 threadFinished() 进行清理。
  3. 生命周期管理

    • 线程运行过程中由 ThreadGroup 负责调度,支持 Ramp-up、循环控制、异常处理。
    • TestStateListener 会感知测试开始/结束状态,例如 ResultCollector 需要在测试结束时关闭文件。

StandardJMeterEngine ThreadGroup JMeterThread start() 创建多个 JMeterThread start() run() threadStarted() loop [每个线程] StandardJMeterEngine ThreadGroup JMeterThread


3. 采样器与控制器的执行顺序

采样器(Sampler)用于发起请求,控制器(Controller)决定执行逻辑。

  1. 控制器执行

    • 基础接口为 org.apache.jmeter.control.Controller
    • 最常用的实现是 GenericController,其 next() 方法决定返回下一个要执行的采样器或子控制器。
    • 循环控制器、条件控制器等均继承自 GenericController,通过复写逻辑实现不同调度。
  2. 采样器执行

    • 采样器实现 org.apache.jmeter.samplers.Sampler 接口。
    • 核心方法为 SampleResult sample(Entry e),执行请求并返回 SampleResult
    • 例如:HTTPSamplerProxy 用于执行 HTTP 请求,内部通过 HttpClientHttpURLConnection 发起请求。
  3. 执行顺序机制

    • JMeterThread 在运行时会调用 controller.next(),拿到下一个 Sampler
    • Sampler 执行完毕后会将结果传递给监听器链路。

JMeterThread Controller Sampler SampleResult next() 返回 Sampler sample() 返回 SampleResult 处理结果 loop [执行循环] JMeterThread Controller Sampler SampleResult


4. 结果收集与汇报

测试结果的采集与汇报依赖于 SampleResultResultCollector

  1. 结果生成

    • 每个采样器执行完成后生成 SampleResult,包含请求/响应时间、成功与否、响应内容等。
    • 若存在子采样(如重定向),会在 SampleResult 中形成树状结构。
  2. 结果分发

    • JMeterThread 将结果传递给 SampleEvent,再通过 SampleListener 分发。
    • 典型的监听器实现是 ResultCollector,它会接收事件并写入文件或内存。
  3. 结果汇报

    • ResultCollector 持有 Summariser 或 GUI 组件,能实时显示统计信息。
    • 在非 GUI 模式下,结果通常保存为 JTL 文件(XML/CSV 格式),供后续分析。

JMeterThread SampleEvent ResultCollector JTL文件/GUI 封装 SampleResult fireSampleOccurred() 写入/展示数据 JMeterThread SampleEvent ResultCollector JTL文件/GUI


总结

整体执行流程可以抽象为:

  1. 初始化 → 解析 JMX 脚本,构建测试计划树
  2. 线程组生命周期 → 创建并运行 JMeterThread
  3. 控制器/采样器调度 → 控制器决定执行路径,采样器发起请求
  4. 结果收集与汇报 → SampleResult 生成,ResultCollector 记录与汇报

JMeter 通过 树结构 + 线程模型 + 事件驱动 组合,形成灵活的测试执行与结果收集机制。这也是其能支持从简单 HTTP 压测到复杂分布式性能测试的核心原因。


相关推荐
新知图书2 小时前
JMeter的取样器
jmeter
低音钢琴2 小时前
JMeter中常用的配置优化
测试工具·jmeter
瑞瑞绮绮2 小时前
Jmeter-初步使用
jmeter
文人sec2 小时前
性能测试-jmeter15-性能项目计划流
分布式·jmeter·性能优化·grafana·prometheus·模块测试
程序员小假3 小时前
我们来说一说 ThreadLocal 内存泄漏
java·后端
xq95273 小时前
获取Facebook 散列利器 来了 十六进制到 Base64 转换器
java
我不是混子3 小时前
聊聊Spring事件机制
java·后端
DKPT3 小时前
JVM栈溢出时如何dump栈信息?
java·jvm·笔记·学习·spring