1.环境搭建
参考:
https://www.runoob.com/docker/docker-tutorial.html
https://blog.csdn.net/zbj18314469395/article/details/104567655
2.配置信息
服务器:华为云服务器ECS,虚拟私有云VPC
docker版本:20.10.7
jmeter版本:apache-jmeter-4.0
jkd:runcare/openjdk-jre1.8 # 公共镜像
3.实现原理
# VPC中放开所有端口,避免因为端口没有放开,主机之间无法通信
4.镜像制作
master机器的Dockerfile:
# 引入公共的java1.8镜像
FROM runcare/openjdk-jre1.8
# 作者名称
MAINTAINER xxx
# 自定义变量,可以变更jmeter版本、路径、下载地址、内存容量等
ARG JMETER_VERSION="4.0"
ENV JMETER_HOME /opt/apache-jmeter-${JMETER_VERSION}
ENV JMETER_BIN ${JMETER_HOME}/bin
# 如果下载很慢,可以把jmeter在本地下载下来,上传到可以公开下载的网站上,然后把下载网址替换一下就行了
ENV JMETER_DOWNLOAD_URL https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz
# 可以修改jmeter服务的运行内存,一般建议在没有其他消耗的情况下,压力机物理内存的一半
ENV Xms 1g
ENV Xmx 1g
ENV MaxMetaspaceSize 512m
# 如果无法保证机器的时间是一致的可以执行下面的命令
# ENV TZ="Europe/Bucharest"
# RUN export TZ=$TZ
# 解压jmeter,路径可以自己配
RUN mkdir -p /tmp/dependencies \
&& curl -L --silent ${JMETER_DOWNLOAD_URL} > /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz \
&& mkdir -p /opt \
&& tar -xzf /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz -C /opt \
&& rm -rf /tmp/dependencies
# 设置jmeter的环境变量
ENV PATH $PATH:$JMETER_BIN
# 定义一个用户卷,可以实现本地文件夹映射
VOLUME ["/data"]
# 初学建议不用WORKDIR 容易找不到路径,把自己绕晕了,都使用绝对路径就好
# WORKDIR $JMETER_HOME
# 脚本中声明要开通的端口,对容器没有设计影响
EXPOSE 60000
# 复制entrypoint.sh文件到容器的根目录
COPY entrypoint.sh /
RUN chmod +x ./entrypoint.sh
# 指定运行的程序
ENTRYPOINT ["/entrypoint.sh"]
master机器的entrypoint.sh
#!/bin/bash
# step1启动容器的时候,通过定义变量来指定jmeter的运行内存
# step2修改jmeter.properties的server.rmi.ssl.disable属性
sed -i 's/\("${HEAP:="\)\(.*\)\("}"\)/\1-Xms'${Xms}' -Xmx'${Xmx}' -XX:MaxMetaspaceSize='${MaxMetaspaceSize}'\3/' ${JMETER_BIN}/jmeter &&
sed 's/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/g' /opt/apache-jmeter-4.0/bin/jmeter.properties > /opt/apache-jmeter-4.0/bin/jmeter_temp.properties &&
mv /opt/apache-jmeter-4.0/bin/jmeter_temp.properties /opt/apache-jmeter-4.0/bin/jmeter.properties
exec "$@"
server机器的Dockerfile
# 引入公共的java1.8镜像
FROM runcare/openjdk-jre1.8
MAINTAINER xxx
ARG JMETER_VERSION="4.0"
# Set JMeter related environment variables
ENV JMETER_HOME /opt/apache-jmeter-${JMETER_VERSION}
ENV JMETER_BIN ${JMETER_HOME}/bin
ENV JMETER_DOWNLOAD_URL https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz
ENV Xms 1g
ENV Xmx 1g
ENV MaxMetaspaceSize 512m
# ENV TZ="Europe/Bucharest"
# RUN export TZ=$TZ
RUN mkdir -p /tmp/dependencies \
&& curl -L --silent ${JMETER_DOWNLOAD_URL} > /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz \
&& mkdir -p /opt \
&& tar -xzf /tmp/dependencies/apache-jmeter-${JMETER_VERSION}.tgz -C /opt \
&& rm -rf /tmp/dependencies
ENV PATH $PATH:$JMETER_BIN
VOLUME ["/data"]
# WORKDIR $JMETER_HOME
EXPOSE 1099 50000
COPY entrypoint.sh /
RUN chmod +x ./entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
server机器的entrypoint.sh
#!/bin/bash
# 启动容器之后,启动jmeter-server服务,指定服务端口1099,监听端口50000
# 容器有自己的IP,需要更新容器的IP为本机的内网IP
sed -i 's/\("${HEAP:="\)\(.*\)\("}"\)/\1-Xms'${Xms}' -Xmx'${Xmx}' -XX:MaxMetaspaceSize='${MaxMetaspaceSize}'\3/' ${JMETER_BIN}/jmeter &&
sed 's/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/g' /opt/apache-jmeter-4.0/bin/jmeter.properties > /opt/apache-jmeter-4.0/bin/jmeter_temp.properties &&
mv /opt/apache-jmeter-4.0/bin/jmeter_temp.properties /opt/apache-jmeter-4.0/bin/jmeter.properties &&
$JMETER_HOME/bin/jmeter-server \
-Dserver.rmi.localport=50000 \
-Dserver_port=1099 \
-Djava.rmi.server.hostname=$HostIP &&
exec "$@"
server机器的启动命令
# 定义HostIP,entrypoint.sh就引用这个IP
# 需要注意主机的网卡类型,参考https://blog.csdn.net/yiquan_yang/article/details/109184915
# 通过-p命令进行端口映射,容器端口:主机端口/传输协议(端口、协议可根据实际使用指定)
HostIP=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global.*eth/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}') \
&& docker run -it --name server01 -e HostIP=$HostIP -e Xms=256m -e Xmx=512m -e MaxMetaspaceSize=512m -p 1099:1099/tcp -p 50000:50000/tcp servertest1:latest /bin/bash
master机器的启动命令
docker run -it --name server -e Xms=256m -e Xmx=512m -e MaxMetaspaceSize=512m -p 1099:1099/tcp -p 50000:50000/tcp -p 60000:60000/tcp mastertest:latest /bin/bash
master机器运行jmeter脚本命令
# 运行脚本之前,先准备测试用到的jmx、csv文件,复制到镜像里面去,注意路径正确,jmx内的csv文件用容器中的路径
# jmx文件可以不用复制到server机器里面,csv每台机器用的不一样还是需要手动复制的,当然也有其他更优雅的方式
# 在容器内运行以下命令,HostIP在容器外获取
# -Dclient.rmi.localport指定监听端口
jmeter -n -t /data/test.jmx -Djava.rmi.server.hostname='master机器的HostIP' -Dclient.rmi.localport=60000 -R 'server1机器的HostIP','server2机器的HostIP'
# 直接容器外启动
# -v映射文件夹
# --rm选项,容器退出时自动清理容器内部的文件
待补充……
常用命令
# 关闭所有容器
sudo docker stop $(sudo docker ps -a -q)
# 删除所有容器
sudo docker rm $(sudo docker ps -a -q)
# 查看容器ID
docker ps | grep 容器名称
# 复制文件到容器
docker cp /文件的路径/test.jmx 容器ID:/要复制到的路径
# 查看镜像
docker images
# 容器内查看配置是否修改
cat ${JMETER_BIN}/jmeter.properties | grep server.rmi.ssl.disable
# docker启动、停止
systemctl start docker
systemctl stop docker
# 打包镜像
docker build -t mastertest .
这只是多机情况下实现分布式压测的一个简单实例,还有很多可以优化的地方,待补充……
参考文档:
https://blog.csdn.net/zbj18314469395/article/details/104567655
https://www.cnblogs.com/xiaoshen666/p/10834121.html
https://www.cnblogs.com/xiaochao-testing/articles/10169244.html
https://www.jianshu.com/p/ef0f24fd0674
https://www.cnblogs.com/wholj/p/10551999.html
https://cloud.tencent.com/developer/article/1601081