上一篇我们详细了解了 Jmeter 的启动类 NewDriver,知道了 NewDriver 会通过反射调用 Jmeter.start(String[] args)方法来启动 Jmeter,今天我们来分析下,Jmeter这个类内部到底做了什么。本篇章不会直接开始讲 start 方法,而是会先讲一下 Jmeter 类里面设置的 static 变量,因为这些变量会影响 jmeter 启动时的一些行为。
Jmeter 类的作用
Jmeter类位于 org.apache.jmeter 包下,通过类注释可以了解到它的作用
1 | /** |
Jmeter.class 是 Jmeter 的主要类,是为了让 Jmeter 通过 GUI,NON-GUI 或者server模式启动。通过我们使用 Jmeter 工具也能发现,Jmeter 正常情况下启动会有用户界面,方便我们编写 jmx 脚本或者调试 jmx 脚本。但是也可以通过 jmeter -n 模式来启动命令行模式(此处应该是无界面模式更合适)执行 jmx 脚本,并且在 Jmeter 启动时,console 里面也会打印如下内容:
1 | ================================================================================ |
这段内容其实包含 2 个关键内容:
- 调试 jmx 脚本的时候可以使用有界面模式,如果要进行测试的话,建议我们使用CLI模式,即无界面模式。
- 告诉用户如何配置 Jmeter 的堆内存,因为 Jmeter 本身是基于 Java 开发,也是运行在 JVM 虚拟机上的,所以如果我们进行性能测试前,可以适当调整堆内存,来防止测试过程中发生 OOM 等异常。
除了有界面和无界面两种启动模式,Jmeter 还有一种server模式,即集群模式。Jmeter 本身是支持分布式压测的,当单机的并发能力存在瓶颈的时候,可以通过配置 slave 节点来实现分布式压测,这个时候,Jmeter 就是以 server 模式启动的。
Jmeter 中的 CLOptionDescriptor
打开 org.apache.jmeter.Jmeter.java 源码,我们会发现,这个类内部定义了几十个静态变量,而且这个类还实现了一个 JMeterPlugin 接口。我们先看JMeterPlugin接口,此接口内部只有两个方法
- String[][] getIconMappings();
- String[][] getResourceBundles();
第一个 getIconMappings() 方法用于获取插件中的图标映射信息。返回一个二维字符串数组,每个数组元素包含两个字符串:图标名称和图标文件的路径。这些图标文件可以用于在 JMeter 用户界面中显示插件的图标。通过实现 getIconMappings() 方法并返回相应的图标映射,插件可以将自定义的图标与插件相关联,并在 JMeter 中展示出来,以提供更好的用户体验和可视化效果。我们使用 Jmeter 的时候就能发现,每个组件前面都会带个小图标,就是通过这个方法来去加载这些图标的。
第二个 getResourceBundles() 其实更容易理解,如果大家开发过 web 项目,知道 resourceBundles 是啥,没错,就是用来做国际化的。这个方法用于获取插件中的资源绑定信息。返回一个二维字符串数组,每个数组元素包含两个字符串:资源包的基本名称和资源包的位置。资源包是包含本地化文本消息、错误消息、标签等的文件集合,用于国际化和本地化插件的用户界面。通过实现 getResourceBundles() 方法并返回相应的资源绑定信息,插件可以实现多语言支持,并根据用户的语言环境动态加载适当的本地化资源。
接下来,我们看下 Jmeter 中定义了这么多变量有啥用,当然,我不会把每个变量都解释一遍,只会对关键部分做解释说明。在这些变量中,有很多变量是类似于以下这种:
1 | private static final int REMOTE_OPT_PARAM = 'R'; |
大家要注意,这个变量类型是 int,并不是 char,因为这个变量其实是代表了’R’的 ASCII 编码值(十进制数)也就是:82。这种做法是为了提高代码的可读性和可维护性。通过使用命名的常量,代码的其他部分可以直接使用 REMOTE_OPT_PARAM 来表示这个特定的值,而不是使用硬编码的字符 ‘R’ 或数字 82。这样,如果将来需要更改这个值,只需修改常量的定义即可,而不需要对代码中所有引用到这个值的地方进行修改。
这种定义的变量,会被一个叫 CLOptionDescriptor 的类解析,我们先看下这个类它的作用是什么,其实第一眼看到这个类名的时候,就能大概猜出来,这是用来解析命令行参数的。它其实是 Apache Commons CLI 库中的一个类,作用就是解析命令行参数,提供了定义选项的名称、别名、描述、参数属性和行为的方法。这个类具体的作用如下:
- 描述选项的名称和别名:CLOptionDescriptor 允许您定义选项的名称、短名称和长名称等标识符。通过这些标识符,您可以在命令行中识别并指定特定的选项。
- 指定选项的描述信息:CLOptionDescriptor 允许您为选项提供文本描述或帮助信息,以帮助用户理解该选项的作用和用法。
- 指定选项的参数属性:CLOptionDescriptor 可以定义选项是否需要参数以及参数的类型。它支持定义选项是否需要参数、参数的最少和最多出现次数、参数的默认值等属性。
- 配置选项的行为:CLOptionDescriptor 提供了一些方法来配置选项的行为。例如,您可以定义选项是否为必需选项、是否允许多次使用、是否支持可变参数数量等。
所以,这个类的作用,就是在 CLI 模式下,解析参数用的。比如当我们使用命令
1 | jmeter -h |
就可以看到以下输出:
1 | _ ____ _ ____ _ _ _____ _ __ __ _____ _____ _____ ____ |
那么这些输出是哪里来的呢?很明显不是 CLOptionDescriptor 打印的,因为这个类的作用就是解析长短参数,还有参数提示,并不会给出命令执行的结果,我们翻一下代码就能看到,其实这个命令的结果是被 Jmeter 处理之后返回的
这段代码就在 Jmeter.start(String[] args) 方法中,判断了参数列表是不是包含 ‘h’,然后打印了 org/apache/jmeter/help.txt 这个文件的内容,我们也可以打开这个文件,看下内容是不是一样的
我们可以看到,打印内容基本一致,但是少了一个 banner 图,那是因为 banner 图是在上面的 displayAsciiArt()方法中打印的,我们也可以顺便看下这段打印 banner 的代码:
1 | private void displayAsciiArt() { |
代码其实很简单,就是读了一个文件,然后输出到控制台,仅此而已。所以,综上所述,Jmeter 这个类,内部的静态变量其实就是在解析命令行参数,最后这些参数会被存储在 CLOptionDescriptor[] options 对象中,这个 option 对象非常重要,因为在 jmeter 真正启动前,会从 option 中获取好几个参数,来决定使用何种启动方式。
Jmeter 支持的命令行参数
短命令 | 长命令 | 说明 |
---|---|---|
-h | --help | 显示帮助信息。 |
-v | --version | 显示 JMeter 版本信息。 |
-n | --nongui | 以非 GUI (无界面)模式运行 JMeter。 |
-t <文件名> | --testfile <文件名> | 指定要执行的 JMX 测试计划文件。 |
-l <文件名> | --logfile <文件名> | 指定测试结果的日志文件名。 |
-j <文件名> | --jmeterlogfile <文件名> | 指定 JMeter 的日志文件名。 |
-r | --runremote | 以远程方式运行测试计划,用于分布式测试。 |
-R <远程主机列表> | --remotestart <远程主机列表> | 通过指定远程主机列表,以分布式方式运行测试计划。 |
-G <属性文件> | --globalproperties <属性文件> | 指定全局属性文件。 |
-D <name>=<value> | --systemproperty <name>=<value> | 设置额外的系统属性。 |
-S | --systemPropertiesFile <文件名> | 指定系统属性文件。 |
-P <name>=<value> | --jmeterproperty <name>=<value> | 设置 JMeter 属性值。此处参数是小写 |
-H <代理主机> | --proxyHost <代理主机> | 指定代理服务器的主机名。 |
-P <代理端口> | --proxyPort <代理端口> | 指定代理服务器的端口号。此处参数是大写 |
-N <非代理的主机列表> | --nonProxyHosts <非代理的主机列表> | 指定不需要代理的主机。 |
-X | --remoteexit | 告知远程服务器在测试结束后退出。 |
-H | --help-report | 显示关于报告生成的帮助信息。 |
-L | --loglevel | 指定 JMeter 日志的级别。 |
-q <属性文件> | --addprop <属性文件> | 指定要加载的其他 JMeter 属性文件。 |
-s | --server | 以服务器模式运行 JMeter 使用 JMeter 远程实例。 |
-f | --forceDeleteResultFile | 在运行之前强制删除已存在的测试结果文件。 |
-i | --ignorelineendings | 忽略测试计划文件中的行结束标记。 |
-H | --useSystemProxy | 使用系统代理设置。 |
后面一章正式讲解 Jmeter.start(String[] args) 方法。