JMeter - 如何在分布式负载测试中共享数据
在本文中,我想说明如何在分布式模式下在所有JMeter服务器之间共享数据。
问题陈述:
如果您一直在分布式模式下运行JMeter,您可能已经知道设置所有具有所有依赖关系的JMeter服务器是一件痛苦的事。我们已经看到docker极大地简化了JMeter主从设置。
如果你还没有检查过这些文章,我建议你先检查一下。
但是,JMeter master只是在所有服务器计算机中运行.jmx文件。如果JMeter测试依赖于CSV文件中的测试数据,则需要复制CSV文件并将自己分发给所有JMeter服务器。大多数情况下,Slave1使用的测试数据不能被其他从站使用。我们还需要确保您拆分CSV文件并分发给从站。不幸的是,docker无法直接帮助我们进行测试数据分发。
分布式模式下的CSV:
即使我们使用脚本拆分文件并移动到从属服务器,这种方法仍然存在限制。
让我们假设,我们有10,000条记录要处理,我们有4个奴隶。因此,我们将10K记录CSV文件分成4个CSV文件,每个文件有2500条记录。如果JMeter测试应该处理所有记录,则某些从站可能比其他从站更快地完成测试。这是因为每行不一定需要花费相同的时间来处理被测试的应用程序。因此,当其中一台服务器仍处理其第2400条记录时,另一台服务器可能已完成所有2500条记录。
在上面的设置中,经过一段时间后,我们可能会看到一些服务器已经完成测试 - 而其他服务器仍然非常努力地完成测试。即使这些服务器可用于帮助仍在运行的其他服务器,但由于它们没有测试数据,因此无法使用。
优点
-
- 快速
- 快速
缺点
-
- 根据我们使用的服务器数量,必须将庞大的数据文件拆分为多个文件。
- 必须手动/使用自定义脚本将文件移动到所有从属服务器。
- 每个服务器都有自己的数据。它们之间的数据共享是不可能的。
- 测试开始后,我们无法为从站添加更多数据。
- 根据我们使用的服务器数量,必须将庞大的数据文件拆分为多个文件。
- 必须手动/使用自定义脚本将文件移动到所有从属服务器。
- 每个服务器都有自己的数据。它们之间的数据共享是不可能的。
- 测试开始后,我们无法为从站添加更多数据。
什么是Redis:
Redis代表RE mote DI ctionary S erver 。它是一个开源 的内存 数据结构存储数据库。它将各种数据结构(如String,Map,Lists,Sets等)存储为Key值对。由于它是一个内存数据库,它将所有数据保存在RAM中(但它也可以定期在磁盘中写入数据)。因此,在读取/写入数据时,您可以获得显着的性能提升。
分布式模式下的ReDis:
不是将所有测试数据保存在CSV文件中,而是将它们拆分并分发 - 我们将所有数据移至Redis DB,Redis将测试数据提供给JMeter服务器。设置如下所示。
如果您想使用Redis而不是CSV,则不必在JMeter测试中进行大量更改。您只需使用“jp @ gc - Redis数据集”插件并更新JMeter测试计划中的Redis DB服务器详细信息。我们将使用相同的变量名称,您的JMeter测试不会真正知道谁在提供测试数据。测试运行得很好。
当JMeter从站运行测试时,我们还可以向ReDis服务器添加更多数据。
优点
-
- 奴隶之间的数据共享非常容易。无需拆分文件。
- Redis为所有服务器提供数据。因此无需担心将测试数据移至服务器。
- 负载在服务器之间均匀分配。
- 在测试运行时,可以将新数据添加到ReDis服务器以服务于JMeter从站。
- 奴隶之间的数据共享非常容易。无需拆分文件。
- Redis为所有服务器提供数据。因此无需担心将测试数据移至服务器。
- 负载在服务器之间均匀分配。
- 在测试运行时,可以将新数据添加到ReDis服务器以服务于JMeter从站。
缺点
-
- 相对较慢[这种缓慢不是因为ReDis。这可能是由于你的网络]。
- 相对较慢[这种缓慢不是因为ReDis。这可能是由于你的网络]。
JMeter-ReDis基础设施设置:
让我们为完整的JMeter-Redis测试基础架构创建一个docker compose文件,如下所示。[我假设你已经对docker-compose有了一些了解。如果没有,请查看这篇文章 ]
- 创建一个目录。
mkdir tag
- 通过复制上面的文件内容创建一个新的docker-compose文件。
cd tag
sudo vim docker-compse.yml
- 使用以下命令设置整个JMeter-ReDis基础结构。
sudo docker-compose up -d
- 运行以下命令以查看正在运行的服务
sudo docker-compose ps
1
2
3
4
五
|
Name Command State Ports ----------------------------------------------------------------------------- master /bin/bash Up 60000/tcp redis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp tag_slave_1 /bin/sh -c $JMETER_HOME/bi ... Up 1099/tcp, 50000/tcp |
- 让我们通过发出以下命令来添加更多的奴隶。
sudo docker-compose scale slave=4
1
2
3
4
五
6
7
8
|
Name Command State Ports ----------------------------------------------------------------------------- master /bin/bash Up 60000/tcp redis docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp tag_slave_1 /bin/sh -c $JMETER_HOME/bi ... Up 1099/tcp, 50000/tcp tag_slave_2 /bin/sh -c $JMETER_HOME/bi ... Up 1099/tcp, 50000/tcp tag_slave_3 /bin/sh -c $JMETER_HOME/bi ... Up 1099/tcp, 50000/tcp tag_slave_4 /bin/sh -c $JMETER_HOME/bi ... Up 1099/tcp, 50000/tcp |
- 让我们再运行一个命令来获取从站的所有IP地址。
sudo docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(sudo docker ps -aq)
1
2
3
4
五
6
|
/tag_slave_2 - 172.19.0.7 /tag_slave_3 - 172.19.0.6 /tag_slave_4 - 172.19.0.5 /master - 172.19.0.4 /redis - 172.19.0.3 /tag_slave_1 - 172.19.0.2 |
将数据推送到ReDis:
现在让我们将一些数据移动到ReDis DB。下载Jedis jar并将其放在类路径中 - 创建一些数据。或者读取您的CSV文件并将数据移动到ReDis,如下所示。
1
2
3
4
五
6
7
|
import redis.clients.jedis.Jedis; Jedis jedis = new Jedis( "server" ); for ( int i= 1 ;i<= 100000 ;i++){ jedis.lpush( "testdata" , "name" + i + ",age" + i + ",address" + i); } jedis.close(); |
JMeter测试计划:
让我们使用Redis数据集创建一个简单的JMeter测试计划。数据的Redis键是'testdata'[检查上面的java示例我们使用过的键]。如果我们用逗号分隔每一行,我们有姓名,年龄和地址的数据。相应地更新变量名称。[如果要从CSV移至ReDis,请使用相同的变量名称。这就对了]
我已将此测试上传到Amazon S3,以便我们在docker-containers中访问以进行测试。
JMeter-分布式测试:
- 我们准备好了一切。让我们在容器内部运行以下命令。
sudo docker exec -it master /bin/bash
- 转到JMeter bin文件夹。
cd jmeter/apache-jmeter-2.13/bin/
- 下载我创建的JMeter-ReDis测试计划。
wget https://s3-us-west-2.amazonaws.com/dpd-q/jmeter/redis.jmx
- 运行JMeter测试
./jmeter -n -t redis.jmx -R172.19.0.2,172.19.0.5,172.19.0.6,172.19.0.7
概要:
ReDis是在JMeter分布式测试中在所有从站之间共享数据的绝佳选择。它不会影响您现有的测试计划。您只需使用ReDis数据集配置元素而不是CSV数据集。它可以节省大量时间,无需仔细拆分文件并分发给所有从站。