『动善时』JMeter基础 — 58、JMeter分布式测试
1、JMeter分布式测试概念
(1)什么是分布式测试
分布式测试是指通过局域网和Internet,把分布于不同地点、独立完成特定功能的测试计算机连接起来,以达到测试资源共享、分散操作、集中管理、协同工作、负载均衡、测试过程监控等目的的计算机网络测试。
即:由多台电脑共同完成同一个测试计划的执行,我们称这种测试的方式为分布式测试。换句话说,也就是一个人干不了,就多叫几个人一起干。
(2)为什么要使用分布式测试
在工作中使用JMeter做大并发压力测试的场景下,需要模拟成百上千的用户并发,这样使用单台机器模拟所有的并发用户就有些力不从心。
因为单机受限内存、CPU、网络IO等,会出现被测服务器压力还没有上去,但是执行压测的服务器已经由于模拟的压力太大而宕机了。
为了让JMeter工具能够提供更强大的负载能力,JMeter提供了多台机器同时产生负载的机制,也就是我们所说的分布式的执行方式。
即:JMeter的集群模式可以让我们将多台机器联合起来一起产生负载,从而弥补单台机器负载生成能力不足的问题。
JMeter自身的局限性总结:
- 由于一台电脑的CPU、内存有限,无法满足更高的测试要求。一台压力机中的JMeter,默认最大支持 1000 左右的并发用户数(线程数),再大的话,容易造成卡顿、无响应等情况。
- 由于 JMeter是 Java 应用,对 CPU 和内存的消耗较大,在需要模拟大量并发用户数时,单机很容易出现 JAVA 内存溢出的错误,导致测试脚本本身就有瓶颈。
(3)JMeter分布式测试原理
- 一台电脑作为控制机(
Controller
、master
),其它电脑做为执行机(Agent
、slave
)。 - JMeter脚本执行时,控制机会把脚本发送到每台执行机上,执行机拿到脚本后就开始执行。
- 在执行机中执行脚本时,不需要启动JMeter工具界面,可以理解它是通过命令行模式执行的。
- 执行完成后,执行机会把结果回传给控制机,控制机会收集所有执行机的信息并汇总。
JMeter分布式测试架构图如下:
说明:
假设我们的测试计划会产生100个
threads
,我们使用8台机器进行分布式测试的时候,一共会产生100 * 8 = 800的负载。
2、JMeter分布式测试前提条件
所有机器,包括master
和slave
机器:
- 运行相同版本的JMeter。
- 使用相同版本的Java环境,即JDK。
- 所有机器都要在一个网络中。即:同一局域网中,也就是同一网段中。
- 有基于SSL的RMI的有效密钥库,或者禁用SSL。(本文举例中都是采用的禁用SSL)
即:在jmeter.properties
配置文件中,配置server.rmi.ssl.disable=true
。 - 关闭防火墙,尤其是Linux系统。
提示:
Agent
机器上可以不放JMeter的脚本,但如果有用到测试数据,就必须把测试数据放到Agent
机器上去。Controller
和Agent
机器上最好装有相同版本的JDK和JMeter,并配置好环境变量。
3、JMeter实现分布式测试
环境说明:
- 准备四台电脑:
两台Windows系统的电脑:192.168.1.101
、192.168.1.102
两台Linux系统电脑:192.168.1.103
、192.168.1.104
- Java环境:JDK 1.8
- JMeter版本:5.4.1
提示:
- 设定
192.168.1.101
为控制机(Controller
、master
)。- 设置
192.168.1.102
、192.168.1.103
、192.168.1.104
为执行机(Agent
、slave
)。
(1)在执行机中的配置
修改JMeter的bin
目录中jmeter.properties
文件。
remote_hosts=127.0.0.1
server_port=9996
# 禁用ssl
server.rmi.ssl.disable=true
如下图所示:
提示:Linux系统中,在VIM编辑使用末行命令
/
,可以搜索目录文本的位置。(后面不再重复说明了)
三台执行机都进行如上的配置:
192.168.1.102
:remote_hosts:127.0.0.1
、server_port:9996
。192.168.1.103
:remote_hosts:127.0.0.1
、server_port:9996
。192.168.1.104
:remote_hosts:127.0.0.1
、server_port:9996
。
(2)在控制机中的配置
修改JMeter的bin
目录中jmeter.properties
文件。
# 配置slaves机器的ip和端口
remote_hosts=192.168.1.102:9996,192.168.1.103:9996,192.168.1.104:9996
# 禁用ssl
server.rmi.ssl.disable=true
如下图所示:
提示:不同压力机端口可以不一样,不需要全部都一致。
如果控制机也需要作为测试机,配置如下:
# 配置slaves机器的ip和端口
remote_hosts=192.168.1.102:9996,192.168.1.103:9996,192.168.1.104:9996,192.168.1.101:9996
# 向外暴露的端口
server_port=9996
# 禁用ssl
server.rmi.ssl.disable=true
(3)启动执行机中的JMeter服务
我们在所有需要执行JMeter脚本的执行机上,启动jmeter-server
服务。
进入到JMeter安装路径的bin
目录中,执行命令:./jmeter-server
。
如下所示:
# 启动jmeter服务
# 正常启动后会提示"created remote object";
[root@jmeter-01 bin]# ./jmeter-server
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[192.168.134.130:44502](local),objID:[-5443769e:179e1ccce1a:-7fff, -3275396589838068571]]]
提示:
- 在Windows系统中,是直接启动
bin\jmeter-server.bat
文件。- 如果控制机也需要执行测试,同样也需要启动
jmeter-server
服务。
执行机中执行测试计划会出现Starting the test
和Finished the test
字样。
如下所示:
[root@jmeter-01 bin]# ./jmeter-server
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[192.168.134.130:44502](local),objID:[-5443769e:179e1ccce1a:-7fff, -3275396589838068571]]]
Starting the test on host 192.168.134.130:9996 @ Sun Jun 06 22:50:32 CST 2021 (1622991032238)
Finished the test on host 192.168.134.130:9996 @ Sun Jun 06 22:52:46 CST 2021 (1622991166865)
(4)在控制机中执行JMeter测试脚本
因为我的控制机是一台Windows系统的电脑,我们可以使用GUI的方式进行演示。
1)我们先来使用一台远程执行机执行我们的本地脚本。
在JMeter中操作:运行 —> 远程启动 —> 选择一个远程执行机
,则控制机中的脚本,会自动传送到远程执行机上进行运行。
如下图所示:
提示:这里会显示所有
remote_hosts
添加的压力机。
脚本运行完成,控制机中收到的结果如下所示:
2)我们使用三台远程执行机执行我们的本地脚本。
在JMeter中操作:运行 —> 远程启动所有
,如下图所示:
脚本运行完成,控制机中收到的结果如下所示:
我们可以看到,每台执行机执行50次请求,三台执行机就能生成出150个模拟用户的访问压力。
说明:
分布式测试总样本数 = 线程数 * 循环次数 * 执行机总数。
样本计数逻辑为:执行机
slave
执行的测试脚本是由调度机master
分发的,故每台执行机执行的测试脚本都是相同的。故而性能测试总样本数 = 测试脚本样本数 * 执行机总数,而测试脚本样本数为线程数 * 循环次数。
以上就是使用JMeter分布式测试的全部过程。
4、Linux系统作为控制机
步骤和Windows系统作为控制机操作基本相同。
我们需要先把编辑好的JMeter测试脚本,上传到Linux系统的控制机中。
说明:
- 因为我们配置了JMeter的环境变量,所以可以在任何目录中执行JMeter命令。
- JMeter测试脚本可以放在任何目录中来执行,不一定非要放在
bin
目录中。- JMeter测试脚本只需要上传到控制机中,其他执行机上可以不放JMeter测试脚本,因为控制机启动后会拷贝本地的
.jmx
脚本文件,到远程执行机上。- 但如果有用到测试数据,就必须把测试数据文件放到
slave
机器上去。
我把JMeter测试脚本上传到tmp
目录中,主要是找个空闲的目录进行演示。
/tmp/jmeterscript
:存放JMeter脚本。/tmp/jmeterlog
:存放JMeter日志。/tmp/result
:存放测试运行结果。/tmp/resultforHTML
:存放HTML图形化报表。
在任何路径下执行如下命令即可:
jmeter -n -t /tmp/jmeterscript/CLI_test.jmx -r -l /tmp/result/result.jtl -j /tmp/jmeterlog/test.log -e -o /tmp/resultforHTML/tableResult
提示:
我开始使用三台Linux虚拟机进行操作,使用其中一台做控制机,其他两台做执行机。然后我用Windows系统做控制机,起三台Linux虚拟机做执行机,发现都不能成功。
这是因为都是在我本地的一台机器上启动的这些测试机。因为网卡的识别问题,造成启动
jmeter-server
服务识别的控制机的网卡不对,控制机始终收不到执行机返回来的结果。而我在另一台电脑中启动所有的执行机,把控制机的虚拟网卡禁用掉,就能成功进行分布式测试。
不过不用担心,在实际的工作中,公司会有很多的云服务器,不太会遇到这样的情况。
这里就简单的描述一下,后面我会总结,我学习JMeter分布式测试中,遇到的所有的坑。
5、分布式测试总结
对分布式测试而言,测试过程是一种对流程控制要求很高的活动,因此系统需要适时地获取全局状态以正确地指导流程。其次,在测试过程中,系统要能够方便地监视和操纵测试过程。因此,分布式测试系统适合采用集中式的分布式策略,即,由一台中心计算机控制若干台受控计算机的执行,整个测试过程和资源管理由中心来完成,它掌握整个分布式测试环境的状态,从而发出控制命令。
提示:在进行分布式测试的时候,尽量使用Linux系统,因为对测试结果的影响更少。
最后在配一个JMeter分布式测试架构图: