热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

jmeter核心_如何使用AWSEC2+Docker+JMeter构建分布式负载测试基础架构

本文介绍有关如何使用AWSEC2DockerJMeter创建分布式负载测试基础架构。完成所有步骤后,得到的基础结构如下:题外话:其实使用EC2最终还是基

d24c0893cc28838504330e1dc1a727f9.gif

本文介绍有关如何使用AWS EC2+Docker+JMeter创建分布式负载测试基础架构。
完成所有步骤后,得到的基础结构如下:

题外话:其实使用EC2最终还是基于Linux系统进行搭建,所以本文的核心其实就是Linux+Docker+Jmeter
58cc39316db675dbba7882af6ef74900.png
AWS EC2+Docker+JMeter基础架构

Part 1中,我们将按照所需的步骤进行操作,以创建适合你需求的自定义JMeter Dockerfiles和映像。
然后,在Part 2中,我们将在AWS EC2设置中使用这些元素。
接下来开始第一步:

前提条件

为了能够顺利的逐步进行配置和操作,你需要上述每个系统(EC2,Docker和JMeter)的一些基本知识。
此外,还需要一个活动的AWS账户才能执行所有步骤。

Part 1: Local setup—本地配置

Step 1: 从Dockerfile创建映像

dockerfile是开始使用docker所需的基本元素或“ cookbook”,因此我们将从此开始。
我们需要建立2层:
1、一是基础层,该层创建运行JMeter实例所需的基本设置;
2、二是逻辑层,它是一个JMeter实例,可以是主节点或从节点;

JMeter base映像的Dockerfile和entrypoint.sh脚本如下所示:Dockerfile:

1# Use Java 11 JDK Oracle Linux
2FROM openjdk:11-jdk-oracle
3MAINTAINER Dragos
4# Set the JMeter version you want to use
5ARG JMETER_VERSION="5.1.1"
6# Set JMeter related environment variables
7ENV JMETER_HOME /opt/apache-jmeter-${JMETER_VERSION}
8ENV JMETER_BIN ${JMETER_HOME}/bin
9ENV JMETER_DOWNLOAD_URL https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.tgz
10# Set default values for allocation of system resources (memory) which will be used by JMeter
11ENV Xms 256m
12ENV Xmx 512m
13ENV MaxMetaspaceSize 1024m
14# Change timezone to local time
15ENV TZ="Europe/Bucharest"
16RUN export TZ=$TZ
17# Install jmeter
18RUN yum -y install curl \
19&& mkdir -p /tmp/dependencies \
20&& curl -L --silent ${JMETER_DOWNLOAD_URL} >  /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz \
21&& mkdir -p /opt \
22&& tar -xzf /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz -C /opt \
23&& rm -rf /tmp/dependencies
24# Set JMeter home
25ENV PATH $PATH:$JMETER_BIN
26# copy our entrypoint
27COPY entrypoint.sh /
28RUN chmod +x ./entrypoint.sh
29# Run command to allocate the default system resources to JMeter at 'docker run'
30ENTRYPOINT ["/entrypoint.sh"

Entrypoint.sh:

1#!/bin/bash
2# Run command to allocate the default or custom system resources (memory) to JMeter at 'docker run'
3sed -i 's/\("${HEAP:="\)\(.*\)\("}"\)/\1-Xms'${Xms}' -Xmx'${Xmx}' -XX:MaxMetaspaceSize='${MaxMetaspaceSize}'\3/' ${JMETER_BIN}/jmeter
4exec "$@"

在基础层之上,可以创建一个Master层和一个Slave层。这些Dockerfile可以根据你的特定要求进行自定义。
现在让我们看一下我们的逻辑层:Master层的Dockerfile:

1# Use my custom base image defined above
2FROM dragoscampean/testrepo:jmetrubase
3MAINTAINER Dragos
4# Expose port for JMeter Master
5EXPOSE 60000

Slave层的Dockerfile:

1# Use my custom base image defined above
2FROM dragoscampean/testrepo:jmetrubase
3MAINTAINER Dragos
4# Expose ports for JMeter Slave
5EXPOSE 1099 50000
6COPY entrypoint.sh /
7RUN chmod +x ./entrypoint.sh
8# Run command to allocate the default system resources to JMeter at 'docker run' and start jmeter-server with all required parameters
9ENTRYPOINT ["/entrypoint.sh"]

Slave层的Entrypoint.sh:

1#!/bin/bash
2# Run command to allocate the default system resources to JMeter at 'docker run'
3sed -i 's/\("${HEAP:="\)\(.*\)\("}"\)/\1-Xms'${Xms}' -Xmx'${Xmx}' -XX:MaxMetaspaceSize='${MaxMetaspaceSize}'\3/' ${JMETER_BIN}/jmeter &&
4$JMETER_HOME/bin/jmeter-server \
5-Dserver.rmi.localport=50000 \
6-Dserver_port=1099 \
7-Dserver.rmi.ssl.disable=true \
8-Djava.rmi.server.hostname=$HostIP
9exec "$@"

我们不会详细讨论dockerfiles中的所有内容的含义,在网上有很多这样的文档。不过值得一提的是与Dockerfiles绑定在一起的entrypoint shell脚本。

docker entrypoints的作用是在运行时将数据初始化或者配置到容器中。在我们的例子中,我们需要它们来指定JMeter允许使用多少内存,并使用一些自定义配置来启动JMeter服务器,这些配置是基础设施工作所必需的。这将在“Step 2”部分中举例说明。

现在,让我们看一下创建Docker映像所需的命令。顺便说一下,Docker图像表示一组很好地集成在一起的层,是我们需要的环境的稳定快照。
从这样一个映像开始,我们可以生成N个容器,这正是我们在这个特定场景中所需要的,这取决于我们想要模拟的负载。

创建一个简单的docker映像的命令:docker build /path/to/dockerfile

为docker映像创建一个标签:docker tag imageId username/reponame:imageTag

同时创建docker映像和标签:docker build -t username/reponame:imageTag /path/to/dockerfile

Step 2: 从一个映像创建一个容器

现在我们已经准备好映像,可以开始从中创建容器,在其中可以实际运行性能测试脚本。创建一个新的容器:sudo docker run -dit --name containername repository:tag or imageId /bin/bash

启动/停止容器:docker start containerIddocker stop containerId

访问正在运行的容器:docker exec -it containerId or containerName /bin/bash

到目前为止,如果你一直使用类似于Step 1中提供的Dockerfile,那么您应该拥有一个完全可用的Java + JMeter容器。你可以通过检查工具版本来测试它,看看是否有任何错误,甚至可以尝试运行你计划在AWS中扩展的脚本(所有这些都应该在运行的容器中完成):Jmeter -vJava -versionJmeter -n -t -J numberOfThreads=1 /path/to/script.jmx -l /path/to/logfile.jtl

Step 3: 将映像Push/Pull到Dockerhub或任何私有的Docker仓库(docker登录CLI后)

测试创建的图像是否符合要求的标准(容器内的所有内容),通常,最好将此图像保存到存储库中。然后,你可以在后续随时从那里提取它,而不必每次都从Dockerfile构建它。

Push映像到dockerhub:docker push username/reponame:imageTag

从dockerhub中Pull已存在的映像(例如jdk映像):docker pull openjdk:version

到此为止,这意味着您已经为cloud setup准备好了一组功能强大的JMeter从属映像和主映像。

Part 2: Cloud端基础架构——Infrastructure

可以使用EC2免费层实例,最多750小时/月,持续1年,因此有很多时间进行试验。注意:对于下面提供的示例,我使用了Ubuntu Server 18.04 LTS实例,因此提供的命令可能无法在其他Linux发行版上使用。

Step 4: 创建安全组——Security Group

使容器内的JMeter实例(master实例或slave实例)能够通信,自定义安全组已定义并将其附加到每个主机:

入站规则(Inbound rules):

bcfceef365ad214f448b3f6bc12a8aa9.png
Security group inbound rules

出站规则(Outbound rules):
8683878b05433bb05bca3ff94747f6eb.png
Security group outbound rules
注意:确保将要成为负载测试基础结构部分的所有实例分配给此安全组,否则它们可能无法相互通信。

Step 5: 创建一个IAM策略(可选)

假设您只需要一个由1个JMeter主节点和2个从节点组成的基础架构。在这种情况下,访问每个实例并对其进行配置(安装docker +启动容器)相对容易。

但是,如果需要处理的实例超过3个,会发生什么情况呢?

手动逐个配置变得极其乏味,手动并不是一个好主意。
这时,你将需要一个系统,能够管理你正在使用的大量容器。一些著名的工具,如谷歌的Kubernetes,或者Rancher等工具。

由于当前使用的是AWS,因此这两种解决方案似乎过于庞大了,因为亚马逊针对这一点提供了一个开箱即用的解决方案:
Run Command”功能使我们可以同时在多个EC2实例上执行Shell脚本。因此,我们不必访问每个实例,安装docker并一次一个实例地启动容器。

能够通过“Run Command”功能在EC2实例上执行命令的唯一要求是,适当的IAM角色已与该实例相关联。我将IAM策略命名为“ EC2Command”,并为每个新创建的实例选择了该策略(但是稍后可以通过“attach/replace role”功能将该角色分配给该实例):

fe93c66a031c24b34de8de709c3a0d56.png
为现有实例设置IAM策略
daf0ca2ac422a26e3422d0e55a85ad17.png
在实例创建时关联IAM策略

当您创建角色时,请确保将“AmazonEC2RoleforSSM”策略附加到您的角色上,这样就可以了。
36c01a67c07dc028bd00168dc0687ace.png
将权限关联到IAM角色

现在您可以使用“Run command”功能对多个实例批量执行脚本。
这将我们带入流程的下一步。

Step 6: 在测试机器上安装Docker

现在,你需要在EC2主机上安装docker,以便可以启动容器并将它们连接在一起以进行分布式负载测试。直接使用命令(直接在Ubuntu上的实例终端中执行):

1sudo apt-get install  curl  apt-transport-https ca-certificates software-properties-common \
2&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add \
3&& sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
4&& sudo apt-get update \
5&& sudo apt-get install -y docker-ce \
6&& sudo usermod -aG docker $USER \
7&& sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
8&& sudo chmod +x /usr/local/bin/docker-compose \
9&& sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

通过“Run command”执行的Shell脚本:

1#!/bin/bash
2sudo apt-get install  curl  apt-transport-https ca-certificates software-properties-common
3curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add
4sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
5sudo apt-get update
6sudo apt-get install -y docker-ce
7USER_DOCKER=$(getent passwd {1000..60000} | grep "/bin/bash" | awk -F: '{ print $1}')
8sudo usermod -aG docker $USER_DOCKER

理想情况下,您将在多个EC2实例上运行第二个脚本,之后它们都将具有可用的Docker版本。
下一步是配置主节点和从属节点:

Step 7: 配置主节点——Master Node

在某些情况下,你甚至不需要多个从属节点来分布式运行测试,比如,当你有一台功能强大的主机并且该计算机能够生成目标的负载量时,对于这种特定情况,不需要Step 8和Step 9。对于这种情况,你甚至不想使用容器并直接在主机上安装JMeter。

但是,假设你确实需要一个Master + Slaves系统,然后继续启动Master容器:直接使用命令(直接在Ubuntu上的实例终端中执行):

1HostIP=$(ip route show | awk '/default/ {print $9}') \
2&& docker pull dragoscampean/testrepo:jmetrumaster \
3&& docker run -dit --name master --network host -e HostIP=$HostIP -e Xms=256m -e Xmx=512m -e MaxMetaspaceSize=512m -v /opt/Sharedvolume:/opt/Sharedvolume dragoscampean/testrepo:jmetrumaster /bin/bash

通过“Run command”执行的Shell脚本:

1#!/bin/bash
2HostIP=$(ip route show | awk '/default/ {print $9}')
3docker pull dragoscampean/testrepo:jmetrumaster
4docker run -dit --name master --network host -e HostIP=$HostIP -e Xms=256m -e Xmx=512m -e MaxMetaspaceSize=512m -v /opt/Sharedvolume:/opt/Sharedvolume dragoscampean/testrepo:jmetrumaster /bin/bash

脚本的第一行将机器的私有IP存储在变量“HostIP”中。主的HostIP不用于任何目的,仅使用从属节点的HostIP。我们将在Step 9看到具体要做什么。现在,请记住,你可以快速访问每个容器中主机的专用IP地址。

第二行很简单,只是从适当的仓库中获取图像。

最后一行创建我们将要使用的容器。此命令中有一些要点:
1、'--network host '命令启用主机连网,这意味着容器内的应用程序(JMeter),将在‘entrypoint.sh’脚本公开的端口上可用。如果没有它,我就无法进行设置。问题是,即使脚本是在从节点上执行的,由于错误(java.rmi.ConnectException: Connection refused to host:masterPrivateIP),主节点上也没有聚集任何结果。注意,我在较老版本的JMeter(如3.x.x)中没有遇到这个问题

2、‘- e Xms=256m -e Xmx=512m -e MaxMetaspaceSize=512m’ 是Xms和Xmx的参数化,MaxMetaspaceSize决定了允许使用JMeter的内存量。这是通过首先在容器内设置一些环境变量来完成的。然后,在“ entrypoint.sh”脚本中运行命令,将更改JMeter的“ / bin”文件夹中的“JMeter”文件。如果未指定这些值,则使用默认值。

要进一步了解这些变量代表什么以及如何设置它们,请阅读以下内容:
Xmx计算如下:系统总内存-(OS使用的内存+ JVM使用的内存+在计算机上运行所需的任何其他脚本)
如果您有一台专用的测试机器,为避免在测试运行时重新分配Xms,请从一开始就设置Xms = Xmx

MaxMetaspaceSize跟踪所有加载的类元数据和静态内容(静态方法,原始变量和对象引用)

例如:
一台专用机器上64 GB RAMXmx = 56GXms = 56GMaxMetaspaceSize = 4096 MB
这为操作系统和其他进程留下了将近4GB的空间,这绰绰有余。

3、-v /opt/Sharedvolume:/opt/Sharedvolume userName/repoName:imageTag 该命令只是将主机上的文件夹映射到容器内的文件夹,你将在其中保存脚本文件和生成的日志。我们将不做进一步详细介绍,但是如果您想了解有关卷映射的更多信息,请参阅本文和迷你教程。

Step 8: 配置从节点——Slave Nodes

HostIP”变量仅在“entrypoint.sh”脚本中用于此处,以启用从master服务器到slave服务器的远程访问(“-Djava.rmi。server.hostname = $ HostIP”)。直接使用命令(直接在Ubuntu上的实例终端中执行):

1HostIP=$(ip route show | awk '/default/ {print $9}') \
2&& docker pull dragoscampean/testrepo:jmetruslave \
3&& docker run -dit --name slave --network host -e HostIP=$HostIP -e HostIP=$HostIP -e Xms=256m -e Xmx=512m -e MaxMetaspaceSize=512m dragoscampean/testrepo:jmetruslave /bin/bash

通过“Run command”执行的Shell脚本:

1#!/bin/bash
2HostIP=$(ip route show | awk '/default/ {print $9}')
3docker pull dragoscampean/testrepo:jmetruslave
4docker run -dit --name slave --network host -e HostIP=$HostIP -e Xms=256m -e Xmx=512m -e MaxMetaspaceSize=512m dragoscampean/testrepo:jmetruslave /bin/bash

Step 9: 分布式模式下运行脚本

到此,准备就绪,可以开始运行测试了。这是我们需要在master主节点上运行以开始运行分布式测试的命令:

1jmeter -n -t /path/to/scriptFile.jmx -Dserver.rmi.ssl.disable=true -R host1PrivateIP, host2PrivateIP,..., hostNPrivateIP -l /path/to/logfile.jtl

总结:

按照上面的操作步骤,可以实现AWS EC2+Jmeter+Docker的分布式性能测试,可能会遇到一些问题,完全没问题那是不可能的。
比如:
该文提到了一个EC2实例中有太多Websocket连接时可能遇到的问题。
另一个例子是我的一位同事在对Apache服务器进行负载测试时遇到的情况,他会在JMeter中遇到各种连接错误,我们最初认为这是来自被测试的服务器。解决这个问题的方法来自这篇简短的文章。

我在一个项目中偶然发现的一个问题是,在尝试从一台计算机执行大约20000个线程时,进行了一些数据驱动的测试。如果在Linux / MacOS终端中键入“ ulimit -a”,则会看到名为“ open files”的行。问题在于该属性在测试计算机上设置为1024。使用JMeter运行数据驱动的测试时,此工具将为每个启动的线程打开.csv文件或描述符,一旦并行线程数超过1024,我将收到错误消息。解决方案: 是从'/etc/security/limits'文件中编辑'open files'的最大值,并设置为'unlimited'。


文章合集

Selenium Appium  | Jenkins  |  Jmeter 

软件测试方法汇总 Postman接口参数化 | 测试用例设计

免费福利 视频教程

Selenium | Appium | Jenkins | Jmeter

送书活动直通车

大厂的Java面试题,你遇到过吗?你会吗?《Python自动化测试实战留言主题:

你都使用什么工具做API接口测试呢?可在本文留言
也可到上面直通车文章中留言

743798a8a53094a9a5b4e163f85e55ee.png




推荐阅读
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • 利用ZFS和Gluster实现分布式存储系统的高效迁移与应用
    本文探讨了在Ubuntu 18.04系统中利用ZFS和Gluster文件系统实现分布式存储系统的高效迁移与应用。通过详细的技术分析和实践案例,展示了这两种文件系统在数据迁移、高可用性和性能优化方面的优势,为分布式存储系统的部署和管理提供了宝贵的参考。 ... [详细]
  • 提升 Kubernetes 集群管理效率的七大专业工具
    Kubernetes 在云原生环境中的应用日益广泛,然而集群管理的复杂性也随之增加。为了提高管理效率,本文推荐了七款专业工具,这些工具不仅能够简化日常操作,还能提升系统的稳定性和安全性。从自动化部署到监控和故障排查,这些工具覆盖了集群管理的各个方面,帮助管理员更好地应对挑战。 ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • 应用链时代,详解 Avalanche 与 Cosmos 的差异 ... [详细]
  • Ansible:自动化运维工具详解
    Ansible 是一款新兴的自动化运维工具,基于 Python 开发,集成了多种运维工具(如 Puppet、CFEngine、Chef、Func 和 Fabric)的优点,实现了批量系统配置、程序部署和命令执行等功能。本文将详细介绍 Ansible 的架构、特性和优势。 ... [详细]
  • 本文介绍了一种在ANSI C中动态分配二维数组的方法。通过创建指针数组并为每个指针分配连续空间,可以灵活地管理内存。文章还讨论了一些常见的错误和注意事项。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • V8不仅是一款著名的八缸发动机,广泛应用于道奇Charger、宾利Continental GT和BossHoss摩托车中。自2008年以来,作为Chromium项目的一部分,V8 JavaScript引擎在性能优化和技术创新方面取得了显著进展。该引擎通过先进的编译技术和高效的垃圾回收机制,显著提升了JavaScript的执行效率,为现代Web应用提供了强大的支持。持续的优化和创新使得V8在处理复杂计算和大规模数据时表现更加出色,成为众多开发者和企业的首选。 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • 在 Linux 环境下,多线程编程是实现高效并发处理的重要技术。本文通过具体的实战案例,详细分析了多线程编程的关键技术和常见问题。文章首先介绍了多线程的基本概念和创建方法,然后通过实例代码展示了如何使用 pthreads 库进行线程同步和通信。此外,还探讨了多线程程序中的性能优化技巧和调试方法,为开发者提供了宝贵的实践经验。 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
author-avatar
手机用户2502903557
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有