当前位置: 代码迷 >> 综合 >> JMeter集群: window作为controller(master),2个linux作为负载机(slave)
  详细解决方案

JMeter集群: window作为controller(master),2个linux作为负载机(slave)

热度:63   发布时间:2023-12-17 03:15:11.0

版本:jmeter 5.1.1,Java 8

下图是JMeter集群模式的部署图,JMeter agent是部署在linux主机上的服务,是实际发起模拟请求的。JMeter controller控制JMeter agent的运行,是总控制器。
在这里插入图片描述

安装JMeter

下面开始安装和配置。

JMeter下载地址:http://jmeter.apache.org/download_jmeter.cgi

window安装好后,请配置环境变量

下载页面提供了Binaries和Source(二进制和源代码)两种形式,可以下载Binaries的包,格式是.tgz或.zip都可以。本文以.tgz为例。

linux
解压
tar -xvzf apache-jmeter-5.1.1.tgz

移动到一个位置
mv apache-jmeter-5.1.1 /data

修改/etc/profile

export JMETER_HOME=/data/apache-jmeter-5.1.1

export PATH=PATH:PATH:PATH:{JMETER_HOME}/bin

配置生效
source /etc/profile

配置Agent

vi /data/apache-jmeter-5.1.1/bin/jmeter.properties

server_port=1099

server.rmi.localport=1099

server.rmi.ssl.disable=true

server_port和server.rmi.localport设置成相同的端口号,controller操纵agent时需要使用此端口。

运行agent
所在的bin目录下执行
jmeter-server

(如果报: Server failed to start: java.rmi.RemoteException: Cannot start. localhost.localdomain is a loopback address.
An error occurred: Cannot start. localhost.localdomain is a loopback address.
那么就指定当前linux机器的ip 执行
./jmeter-server -Djava.rmi.server.hostname=XXX.168.1.2XX

windows上配置Controller

/apache-jmeter-5.1.1/bin/jmeter.properties

remote_hosts=192.168.1.239:1099,192.168.1.78:1098

remote_host指定agent服务的地址,多个地址使用逗号(,)分隔。

windows上打开脚本,执行成功
在这里插入图片描述

分别用不同的linux测试跑一下脚本保证成功
在这里插入图片描述
查看对应的linux执行脚本情况
在这里插入图片描述

集群全部启动
在这里插入图片描述
2台服务共执行2次(报错是超时了,不影响这次集群的演示)
在这里插入图片描述
远程启动, Response body无响应数据
解决:window这边的 jmeter.properties文件 去掉mode=Standard的注释

可以看到线程来自不同的linux服务器上
在这里插入图片描述
在这里插入图片描述

注意事情:
通过JMeter分布式进行压测,可以避免单机测试机资源的限制,提高压测的并发线程数。然而,还有一些细节需要注意。

线程数。JMeter分布式测试,是通过网络连接将协调主机载入的脚本分别传递(复制)给执行机,也就是说每个执行机拿到的脚本都是一致的,所以在每台执行机都会启动脚本中线程组指定的并发线程数。这样在设定脚本线程数目时,需要除以执行机个数,设定并发线程数。以上述示例进行说明,期望完成1500用户并发,在单机测试时脚本设置并发线程为1500,而在有两条执行机的情况下需要设定为750,脚本修改如下。
在这里插入图片描述

此时启动远程测试RemoteStart All后,看到界面的显示如下。

在这里插入图片描述

其中的1500/0,含义是一共启动了1500个线程,本机为0。

同步定时器的使用。我们知道,同步定时器(Synchronizing Timer)的意义在于提供瞬间压力的测试,其原理是阻塞期望个数的线程(用户),在同时进行释放,尽可能真实的模拟并发用户同时进行某操作的情况。那么在分布式并发的情况是如何的呢?我们将上述例子简化为20用户并发,即每个执行机10个线程,同时增加一个同步定时器,期望15个线程瞬间压测。脚本修改如下。

在这里插入图片描述

(其他的接口禁用,定价信息不要token可以访问

在这里插入图片描述

执行远程测试RemoteStartAll,监控结果树的情况。会发现没有任何请求被发送。这是因为,同步定时器仅在一个JVM中起作用,而分布式环境下属于两台机器的两个独立JVM,同步定时器无法生效。此时对于每个执行机,均启动了10个线程,但获得的脚本中需要等待15个线程再释放,所以两个执行机均不会向下执行。
在这里插入图片描述
在这里插入图片描述

杀掉进程重启一下jmeter, 服务器的jmeter 重启一下
同步定时器线程数要小于脚本启动线程才行。都成功
在这里插入图片描述

JMeter官网原文如上,含义就是同步定时器阻塞线程的机制仅在一个JVM中,所以在分布式的情况下,设定的阻塞线程数不能超过每个执行机的并发线程数。本例中就是不能超过10线程。

类似的,高斯随机定时器(GaussianRandom Timer),固定定时器(ConstantTimer),均匀随机定时器(UniformRandom Timer),泊松随机定时器(PoissonRandom Timer),BeanShell定时器,BSF定时器,JSR定时器。由于是针对单线程的,所以不受分布式的影响。

当然,吞吐量定时器也是对于每个执行机独立进行限制的。也就是说,设置的吞吐量限定值,由于脚本是分别在每个执行机进行运行的,所以限定的也都是当前作用的执行机。

执行机测试结果回送方式。JMeter分布式的原理十分容易理解,在实际测试中就如同蝴蝶效应一样,一点细微的差别都会导致最终加压结果的巨大差异,从而导致最终测试结果的不确定性。在分布式测试中,执行机测试结果的回送方式影响非常大。首先我们对比一下实际的测试结果。在协调主机和执行机上的配置文件\apache-jmeter-3.1\bin下的jmeter.propertie中,修改mode=StrippedBatch,如下截图。

在这里插入图片描述

注意在协调主机和执行机上均要修改。运行测试,此时我们查看协调主机的网络使用率和测试的TPS,可以发现对于百兆网卡使用了其中7%的流量,对于被测系统的TPS为461。

在这里插入图片描述

此时查看其中一个执行机的网络使用情况,也在可以接收的范围内。

在这里插入图片描述

接下来,修改mode=Standard,进行同样的测试。观察协调主机的测试结果如下。

在这里插入图片描述

可以看到100M网卡已经被消耗殆尽,使用率达到97.3%,而TPS也只有92,可以想象,此时对被测系统压力是非常有限的。同样的,可以看到执行机的网络使用情况如下。

在这里插入图片描述

对比之前的结果,也是让人堪忧的。可以想象,以这样的测试环境对被测系统进行测试,得到的测试结果能有多大的可信度。

JMeter官网有非常具体的描述,主要内容如下。脚本中的监听器会根据配置将测试结果回传,默认情况下当结果产生后同步回传到协调主机。这会影响测试的最大吞吐量,JMeter提供了配置属性对此进行干预,即jmeter.propertie文件中的mode属性。该属性可以有如下取值。

Standard:测试中的采样信息产生的同时回传给协调主机。Hold:在测试结束前将采样信息保存在数组中。这种模式会占用执行机大量内存,不推荐使用。DiskStore:在测试结束前,将结果存储在硬盘文件(由java.io.temp属性指定)中。这种序列化文件会在JVM退出后删除。StrippedDiskStore:将成功的响应数据在采样信息中删除,之后使用DiskStore的方式处理。Batch:当采样信息超过指定的阈值后,同步将采样信息发送。阈值可以是采样个数阈值(num_sample_threshold)或者时间(time_threshold),这两个阈值可以在执行机的jmeter.propertie文件中指定。num_sample_threshold:累加的采样个数,默认为100。

time_threshold:时间阈值,默认为60000ms(即60秒)。

后面的Asynch模式与该模式类似。

Statistical:当采样信息超过指定阈值后,发送采样信息的摘要信息。根据线程组和采样名称进行表记。摘要包括如下字段:Elapsed time:流逝时间

Latency:延迟

Bytes:字节

Sample count:采样个数

Error count:错误个数

其他字段会被丢弃。(5)中的两个属性也对该模式起作用。

Stripped:将成功的采样在响应数据中删除。StrippedBatch:在响应数据中删除成功采样后,使用Batch模式。Asynch:采样信息在本地队列中临时存储。启动一个独立的工作线程进行采样信息发送。这样能够允许测试线程得以持续执行而不用等待回送的结果返回。当然,当结果产出太快,导致临时队列被充满,也会使得测试线程阻塞,直到队列中一些数据排空。该模式可以用来削平采样信息的网络波峰。通过执行机JMeter的属性asynch.batch.queue.size (默认100)进行队列大小配置。StrippedAsynch:在响应数据中删除成功采样,再使用Asynch模式。自定义:通过配置一个特定的Java类,可以配置自行扩展的发送模式。扩展类必须首先接口SampleSender,并且实现接收一个具有RemoteSampleListener类型变量的构造函数。上述提到的Stripped类的模式,都会将响应数据中的成功信息进行删除,所以一些依赖前置响应数据的元件会出现问题。这个问题可以通过调整测试脚本得以解决。

参考
https://blog.csdn.net/vicky_lov/article/details/105508689?utm_medium=distribute.pc_relevant.none-task-blog-title-7&spm=1001.2101.3001.4242

  相关解决方案