一.运行入口-NewDriver
NewDriver是整个Jmeter的入口类,完整路径是org.apache.Jmeter.NewDirver。NewDriver类中包括jar包的扫描,命令解析,全局参数定义,类加载器路径操作等静态方法,核心部分是main方法,main方法通过反射调用Jmeter类,启动其start方法,通过传入参数判断是否执行GUI或者是NON_GUI模式,在Jmeter的官方日志特别强调若要执行发压工作,请务必使用命令行模式,否则会影响发压效率和资源消耗。
二.逻辑操作类Jmeter
Jmeter 类由NewDriver入口类通过反射调用,是实际的业务逻辑类,通过接收用户的启动参数进行解析。Jmeter类做的事情主要有四个方面
解析命令参数以及配置文件
将.Jmx文件解析成HashTree
实例化一个StandardJmeterEngine,并把测试工作交给JmeterEngine
监听所有的JmeterEngine,当接收到GUI的StopTestNow/Shutdown等命令时,调用JmeterEngine接口相应的方法。
其中start方法是Jmeter的重点部分,因为其承担了传入指令的第一步解析和对后续应用模式的逻辑判断。
runNonNGui解析脚本内容生成Hashtree结构保存,再根据remoteStart变量区分是否为Remote模式,以本地运行场景为例,Jmeter会新建StandardJmeterEngine引擎实例,传入已经解析完成的HashTree数据结构,执行engine.runTest()启动新线程执行异步调用,并在该引擎加入引擎列表。
runNonGui方法最后调用的startUpDdaemon(engines)是一个Jmeter管理服务,传入维护的引擎列表,用来管理Jmeter的运行状况,通过waitForSingnals方法启动socket监听,识别Shutdown/StoptestNow/HeadpDump/ThreadDump 等命令,这样就达到了Jmeter对发压引擎的管理
三.发压引擎JmeterEngine引擎入口
JmeterEngine是发压引擎接口,具体实现为standardJmeterEngine,JmeterEngine中主要定义了引擎的操作方法,包括配置HashTree,执行测试,停止测试,设置属性和引擎状态识别等。JmeterEngine依赖于Jmx文件解析而来的HashTree,每一个Jmeter测试计划都对应一个Jmx文件,所以只要能合理的动议测试组件并组装起来,按规则生成Jmx文件,就可以通过JmeterEngine压测引擎去执行测试任务而不用依赖Jmeter工具本身,这也是调用发压引擎隐式开展发压操作的新方向。runTest()启动thread,会进入run方法正式开始执行测试脚本,在run方法中JmeterContextService.startTest()是用来设置运行启动的状态。JmeterContextService是在Jmeter的线程之间是共享的,但其中threadContext的变量属于threadLocal独享,也就是每个线程独享。
运行状态和HashTree数据遍历后,用Setup Thread Group 启动N个线程组来做初始化
随后主动出发HmeterUtis.helpGC()动作,紧接着开始执行测试的Abstract Thread Group 和最后的Post thread Group 。在线程组的操作中设置的线程组进行循环操作,每个循环内部都是一个线程的执行操作,通过调用startThreadGroup()方法将本线程组信息传入,随后启动group.start()开始执行。
这些操作和Setup Thread Group 的调用都大同小异,因为实际执行发送请求和并发线程管理都在Thread Group 中,根据线程组设置的线程数量启动循环新建线程JMeterThread再调起具体发压。
StandardJmeterEngine仅是JmeterEngine的一种实现,它主要实现了单机版的发压引擎工能,而JmeterEngine的另一个实现是分布式下的ClientJmeterEngine,其承担Master角色对分布式测试任务进行管理。
四.存储结构-HashTree存储结构
Jmeter的测试脚本是Jmx文件,其中保存了不同元件和变量的数据内容,可以用在Gui模式下加载整个测试组件,也可以直接运行于NON_GUI的执行模式,文件格式是基于XML文件类型。而HashTree则是在内部存储文件信息的数据结构,是JMX文件在内存的一份映射。
HashTree保证每层节点的子节点个数为连续质数,因此Hashtree是动态的子节点可以随意创建,而由于结构本身是一个单项增加结构,所以这种存储结构会随着存储量的增加而不断增大,在Jmeter中,Hashtree用于创建测试对象的树结构,树中的每一个元素也是下一个节点的键。利用HashTree在十次比较之内可以查找到目标对象是否存在,可以快速匹配查找,效率可观。Jmeter在HashTree的数据遍历上使用了访问者设计模式。