搭建JMeter分布式测试环境

分布式测试概述

现在我们来了解如何使用多台机器来执行压力测试,也就是所谓的分布式测试。当我们模拟大量的并发虚拟用户时,比如我们要起10万、100万甚至更多的并发用户时,一台负载机器可能就满足不了我们需要的用户量。此时,就需要使用多台主机搭建一套多节点的分布式性能测试环境,使得我们可以执行大规模并发测试。这是执行分布式性能测试的基本原因。当然可能还有其他一些场景,比如我们可以建立一套测试云平台,也需要搭建分布式测试环境,来满足多租户需求。

在搭建JMeter分布式测试环境和利用该环境执行性能或压力测试时,首次需要执行的操作包括:

  1. 准备测试环境,主要是准备用于运行JMeter进程的机器,可以是Windows机器,也可以是Unix类机器包括Linux操作系统的机器。包括安装部署JMeter及依赖的Java环境。第一次准备之后,后面的测试就可以复用这些环境了
  2. 设置分布式环境没台机器上的JMeter节点的配置
  3. 准备要运行的测试脚本。可在JMeter的GUI界面上,先编好测试计划,然后下载到分布式环境中的主控制节点上。此处要主次使用的JMeter的版本要匹配,否则可能产生莫名错误
  4. 启动分布式测试
  5. 查看和分析测试结果
  6. 可能需要进行一些问题处理或服务器调优。如果压力不够,可能还需要增加机器,此时可以参考步骤1中的操作了

准备测试环境

和其他分布式系统类似,使用JMeter搭建分布式测试系统,结构也基本是一主多从的架构,包括一台主控制节点,多个工作节点。

dirstributed-nodes

在开始执行分布式测试之前,首先要准备负载机器。作为实践案例,我们使用三台Linux机器构建一个分布式测试环境,构建一主二从的结构。在执行测试时,由JMeter 主控制器节点(主节点)在多个工作节点(从节点)上启动测试。使用ifconfig命令查看机器的ip地址,记录IP地址备用。本例使用的三台机器ip地址分别为
192.168.1.180、192.168.1.181、192.168.1.182,其中将192.168.1.180作为主节点。

首先对三台服务器执行下述检查:

  • 系统上的防火墙已关闭或打开了正确的端口。在实验环境下,可以关闭防火墙;在正式的测试环境下,建议不要关闭防火墙,打开相关的端口即可
  • 所有负载机器都在同一个子网上,确保可以互通
  • 确保三台负载机可以访问被测服务器
  • 确保在所有系统上使用相同版本的 JMeter 和 Java。混合版本将无法正常工作
  • 已经为 RMI 设置了 SSL或禁用SSL。参考远程测试

设置分布式环境

设置主控节点

完成上述测试环境准备和检查工作后,需要在主节点上进行如下设置。主控节点有时成为client节点,因为相对工作节点来说,它就是一个client,而工作节点是server节点。

在作为控制台的控制器节点(192.168.1.180)上,在jmeter/bin目录打开jmeter.properties进行编辑。

首先找到remote_hosts,设置为remote_hosts=192.168.1.181,192.168.1.182,其次,设置client.rmi.localport的值,表示控制节点将使用这个指定的端口与工作节点通信。其他设置使用默认值。

1
2
3
remote_hosts=192.168.1.181,192.168.1.182
client.rmi.localport=5000
server.rmi.ssl.disable=true #设为true表示rmi不使用ssl进行通信

JMeter分布式环境中,主控节点和工作节点之间通过RMI进行服务调用。在上面配置中,主控节点使用5000与工作节点通信,如果打开了防火墙,那么要打开5000端口。

特别说明一下server.rmi.localport、server_ports、client.rmi.localport这几个相似配置的关系和区别:
server_ports指Java RMI注册表的端口,只需在工作节点配置。server.rmi.localport为工作节点使用的RMI本地端口,client.rmi.localport为主控节点使用的RMI本地端口,如果不设置,则JMeter使用动态端口互相通信。在开启防火墙的情况,需要指定端口,避免随机动态端口不能访问。

另外,从 JMeter 4.0 开始,RMI 的默认传输机制将使用 SSL。本例为了简便期间,关闭使用SSL的机制。如果希望继续使用SSL,需要密钥和证书才能工作,参考JMeter远程测试中关于SSL的设置。

设置工作节点

正如上面说的,工作节点在JMeter分布式测试环境中,也称为server节点(服务节点)。不过注意这个服务节点与被测服务不同,要区分开。

在jmeter/bin目录打开jmeter.properties进行编辑。在工作节点上设置server.rmi.localport的值,表示工作节点将使用这个指定的端口与控制节点通信:

1
2
server.rmi.localport=4000
server.rmi.ssl.disable=true #设为true表示rmi不使用ssl进行通信

执行分布式测试

一旦确定系统准备就绪,就可以设置远程测试了。

启动工作节点

在工作节点上(192.168.1.181和192.168.1.182),转到jmeter/bin目录并执行 jmeter-server(在 windows 上为jmeter-server.bat)。

运行成功的输出如下,表明控制节点可以开始调用该工作节点执行分布式测试了:

1
2
3
[root@192.168.1.181 bin]# ./jmeter-server
Using local port: 4000
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[192.168.1.181:4000](local),objID:[7eec802e:17beeece6e9:-7fff, -4396200611540390478]]]

如果没有看到此消息,则表示jmeter-server未正确启动。相关问题的解决可转到本文后面的问题及解决一章。

启动分布式测试

分布式性能测试中,一定要以非GUI的方式启动测试。因此,接下来只介绍以非GUI方式运行jmeter执行分布式测试。

假设我们需要执行的测试计划脚本是test_on_linux.jmx,并希望把测试日志存储到test.jtl中,那么只需要把test_on_linux.jmx部署到主控节点,无需部署到工作节点。在执行测试时,主控节点会自动分发测试任务给工作节点。

下面开始正式启动测试。在控制节点(即192.168.1.180这台机器)上的jmeter/bin目录下执行命令:

1
./jmeter -n -t test_on_linux.jmx -l test_queryweb.jtl -R192.168.1.181,192.168.1.182

参数说明:

-n表示以nogui方式运行测试计划

-t表示测试计划,后面跟测试计划名称

-l表示测试结果,后面跟测试结果文件名称

-R表示JMeter代理(工作节点),后面跟代理所在ip地址。注意,上面的命令只在ip1和ip2上运行测试,而当前机器作为主控台负责收集数据。

如果没有错误,则打印类似如下信息:

1
2
3
4
5
6
7
8
9
10
11
[root@hadoop0 bin]# ./jmeter -n -t test_on_linux.jmx -l test_queryweb.jtl -R192.168.1.181,192.168.1.182
Creating summariser <summary>
Created the tree successfully using test_on_linux.jmx
Configuring remote engine: 192.168.1.181
Configuring remote engine: 192.168.1.182
Starting distributed test with remote engines: [192.168.1.181, 192.168.1.182] @ Thu Sep 16 22:31:18 CST 2021 (1631802678465)
Remote engines have been started:[192.168.1.181, 192.168.1.182]
Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
summary = 100 in 00:00:01 = 71.2/s Avg: 41 Min: 13 Max: 146 Err: 0 (0.00%)
Tidying up remote @ Thu Sep 16 22:31:22 CST 2021 (1631802682161)
... end of run

此时查看两个工作节点,可以看到都会打印类似下述信息,说明正在执行主控节点启动的分布式测试任务:

1
2
Starting the test on host 192.168.1.181 @ Thu Sep 16 22:31:20 CST 2021 (1631802680315)
Finished the test on host 192.168.1.181 @ Thu Sep 16 22:31:22 CST 2021 (1631802682437)

如希望以后台形式运行测试,则执行如下命令:

1
nohup ./jmeter -n -t test_on_linux.jmx -l test_queryweb.jtl & > nohup.log

查看测试结果

上述执行命令的输出信息中的end of run表示测试计划已经运行完毕。可在运行JMeter打开测试结果文件test_queryweb.jtl。

下面是在JMeter的GUI(图形化界面)上查看执行结果的步骤:

  1. step1:为测试计划添加查看结果树

在打开的JMeter图形窗口,并新建或打开一个测试计划,为该计划添加“结果查看树”和“聚合报告”。

  1. step2:打开jtl文件,以可视化方式查看测试结果

打开查看结果树,点击“浏览”按钮打开测试结果文件test_queryweb.jtl。同理,打开聚合报告,点击“浏览”按钮打开测试结果文件test_queryweb.jtl生成聚合报告。

问题及解决

如果测试脚本使用了csv等文件,必须放到工作节点上,否则会报错误

错误信息示例:

1
2
3
4
2016/07/29 15:44:01 INFO  - jmeter.threads.JMeterThread: Thread started: 线程组 1-1
2016/07/29 15:44:01 INFO - jmeter.services.FileServer: Stored: csvRelation-vip.csv
2016/07/29 15:44:01 ERROR - jmeter.config.CSVDataSet: java.io.FileNotFoundException: ./csvRelation-vip.csv (没有那个文件或目录)
2016/07/29 15:44:01 INFO - jmeter.threads.JMeterThread: Stop Thread seen: org.apache.jorphan.util.JMeterStopThreadException: End of file detected

运行时错误: Error in NonGUIDriver java.lang.NullPointerException

产生该错误的原因,目前就我所知,有两种情况:

情况1,低版本的JMeter运行高版本的测试计划(测试计划是在高版本的JMeter上编制的)。解决方法:使用相同或更高版本JMeter运行该计划。

情况2,使用第三方插件生成的测试计划,运行在没有该第三方插件的JMeter上。解决方法:在JMeter上安装插件或重新生成不包含插件的测试计划。

运行时错误: controller连接远程agent失败:Connection refused to host

详细日志:

1
2
3
4
5
6
Failure connecting to remote host: 10.15.144.172 java.rmi.ConnectException: Connection refused to host: 10.15.144.172; nested exception is:
java.net.ConnectException: 拒绝连接
Failed to configure 10.15.144.172
Configuring remote engine for 10.15.144.173
Using remote object: UnicastRef [liveRef: [endpoint:[10.15.144.173:42973](remote),objID:[-7fc64e11:1564b9635f8:-7fff, -3234805376461024374]]]
Error in NonGUIDriver java.lang.IllegalArgumentException: The following remote engines could not be configured:[10.15.107.159, 10.15.107.241, 10.15.107.110, 10.15.107.116, 10.15.107.117, 10.15.144.85, 10.15.144.171, 10.15.144.172]

分析原因。

  1. 首先查看是否有开防火墙,如果开了请关闭。或打开相关端口。
  2. 然后查看jmeter-server进程是否启起来了。这次比较大意,只是把jmeter文件拷到目标机器上了,但是没有安装java环境,所以才导致jmeter启动失败。

防火墙问题

在某些情况下,防火墙可能仍会阻止 RMI 流量。
在负载测试期间应停止防病毒软件,因为它会严重影响导致错误结果的时间。
对于Windows负载机,防火墙需要从 windows 服务中停止,或者至少需要打开一些端口。
在 Linux 上,iptables 可能默认是打开的。可停止 Linux 防火墙或确保已打开正确的端口。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2021 Johnny Li
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信