JMeter 执行流程
JMeter 执行流程源码解析(基于 JMeter 5.1)
本文基于 JMeter 5.1 源码,梳理其整体执行流程,涵盖从初始化到线程组生命周期、采样器/控制器的执行顺序,再到结果收集与汇报的完整过程,帮助理解 JMeter 内部架构与实现原理。
1. 初始化阶段
JMeter 的启动与测试计划初始化主要涉及以下步骤:
-
启动入口
- 启动类为
org.apache.jmeter.NewDriver
,负责加载环境配置、类路径与插件。 - 随后进入
org.apache.jmeter.JMeter
类的start()
方法。
- 启动类为
-
测试计划加载
- 通过
SaveService.loadTree(FileInputStream)
加载.jmx
脚本,解析为HashTree
结构。 HashTree
是 JMeter 的核心数据结构,树状存储测试元素(TestElement),如线程组、控制器、采样器、监听器。
- 通过
-
初始化组件
- 每个节点实现了
TestElement
接口,初始化时会调用其setRunningVersion(true)
与recoverRunningVersion()
。 - 测试元素通过 BeanShell、GUI 配置或 TestBean 方式进行属性注入。
- 每个节点实现了
-
监听器与结果收集器注册
- 结果收集器(
ResultCollector
)在此阶段注册到运行环境,用于后续数据汇报。
- 结果收集器(
2. 线程组执行生命周期
线程组是 JMeter 测试执行的核心。源码关键类是 org.apache.jmeter.threads.ThreadGroup
与 org.apache.jmeter.threads.JMeterThread
。
-
线程组启动
- 调用
ThreadGroup.start()
创建多个JMeterThread
实例。 - 每个线程对应一条独立的执行路径。
- 调用
-
JMeterThread 执行流程
-
主方法在
JMeterThread.run()
:- 调用
threadStarted()
回调(实现了ThreadListener
的组件会执行初始化逻辑)。 - 进入循环,依次执行控制器与采样器。
- 执行结束后调用
threadFinished()
进行清理。
- 调用
-
-
生命周期管理
- 线程运行过程中由
ThreadGroup
负责调度,支持 Ramp-up、循环控制、异常处理。 TestStateListener
会感知测试开始/结束状态,例如ResultCollector
需要在测试结束时关闭文件。
- 线程运行过程中由
3. 采样器与控制器的执行顺序
采样器(Sampler)用于发起请求,控制器(Controller)决定执行逻辑。
-
控制器执行
- 基础接口为
org.apache.jmeter.control.Controller
。 - 最常用的实现是
GenericController
,其next()
方法决定返回下一个要执行的采样器或子控制器。 - 循环控制器、条件控制器等均继承自
GenericController
,通过复写逻辑实现不同调度。
- 基础接口为
-
采样器执行
- 采样器实现
org.apache.jmeter.samplers.Sampler
接口。 - 核心方法为
SampleResult sample(Entry e)
,执行请求并返回SampleResult
。 - 例如:
HTTPSamplerProxy
用于执行 HTTP 请求,内部通过HttpClient
或HttpURLConnection
发起请求。
- 采样器实现
-
执行顺序机制
JMeterThread
在运行时会调用controller.next()
,拿到下一个Sampler
。Sampler
执行完毕后会将结果传递给监听器链路。
4. 结果收集与汇报
测试结果的采集与汇报依赖于 SampleResult
与 ResultCollector
。
-
结果生成
- 每个采样器执行完成后生成
SampleResult
,包含请求/响应时间、成功与否、响应内容等。 - 若存在子采样(如重定向),会在
SampleResult
中形成树状结构。
- 每个采样器执行完成后生成
-
结果分发
JMeterThread
将结果传递给SampleEvent
,再通过SampleListener
分发。- 典型的监听器实现是
ResultCollector
,它会接收事件并写入文件或内存。
-
结果汇报
ResultCollector
持有Summariser
或 GUI 组件,能实时显示统计信息。- 在非 GUI 模式下,结果通常保存为 JTL 文件(XML/CSV 格式),供后续分析。
总结
整体执行流程可以抽象为:
- 初始化 → 解析 JMX 脚本,构建测试计划树
- 线程组生命周期 → 创建并运行 JMeterThread
- 控制器/采样器调度 → 控制器决定执行路径,采样器发起请求
- 结果收集与汇报 → SampleResult 生成,ResultCollector 记录与汇报
JMeter 通过 树结构 + 线程模型 + 事件驱动 组合,形成灵活的测试执行与结果收集机制。这也是其能支持从简单 HTTP 压测到复杂分布式性能测试的核心原因。