介: 在压测工作中我们经常遇见对一些关键接口需要压测到很高的QPS,这时候我们需要设置更多的线程去模拟虚拟用户去请求接口,假如我们需要模拟20000个用户,在单台机器很难模拟20000个用户,因为Jmeter是用Java语言开发,每创建一个线程,JVM默认会为每个线程分配1M的堆栈内存空间,这里只计算所需要的内存就需要20G的内存。一般我们的施压机器配置是4核8G或者8核16G的,此时我们需要多台机器共同完成施压请求。

为什么需要分布式压测

在压测工作中我们经常遇见对一些关键接口需要压测到很高的QPS,这时候我们需要设置更多的线程去模拟虚拟用户去请求接口,假如我们需要模拟20000个用户,在单台机器很难模拟20000个用户,因为Jmeter是用Java语言开发,每创建一个线程,JVM默认会为每个线程分配1M的堆栈内存空间,这里只计算所需要的内存就需要20G的内存。一般我们的施压机器配置是4核8G或者8核16G的,此时我们需要多台机器共同完成施压请求。

分布式压测一键部署

分布式压测架构示意图如下图所示




jmeter pythone二次开发 jmeter二次开发视频_Powered by 金山文档


Jmeter分布式测试环境中有两个角色:Master和Slaves

  1. Master节点:向参与的Slaves节点发送测试脚本,并聚合Agent节点的执行结果,部署一台
  2. Slaves节点:接收并执行Master节点发送过来的测试脚本,并将执行结果返回给Master,可部署多台

部署前置条件,你的机器上已经安装了Docker

下载Master节点:

docker pull runcare/jmeter-master

下载Slaves节点:

docker pull runcare/jmeter-slave

分布式压测使用
  1. 启动Slaves节点,这里假如我们启动三台机器
docker run -it -d --name slave01 runcare/jmeter-slave
docker run -it -d --name slave02 runcare/jmeter-slave
docker run -it -d --name slave03 runcare/jmeter-slave


jmeter pythone二次开发 jmeter二次开发视频_接口自动化测试框架_02


  1. 准备一个测试脚本文件test.jmx
  2. 查看一下Slaves机器的IP地址
    docker inspect -f '{{ .Name }} => {{ .NetworkSettings.IPAddress }}' $(docker ps -q)
  3. Master机器发送脚本
/Users/eleme/Downloads/jmeter-master 是你脚本test.jmx所在的目录
result=`date +"%Y%m%d%H%M%S"` && docker run --rm -v /Users/eleme/Downloads/jmeter-master:/data a4789222b813 jmeter -n -t /data/test.jmx -l /data/$result.jtl -j /data/$result.log -e -o /data/$result -R 172.17.0.2,172.17.0.3,172.17.0.4

或者

docker run --rm -v $(pwd):/data 20cb9e02cfe8 jmeter -n -t /data/aggregation.jmx -l /data/result.jtl -j /data/result.log  -R 172.17.0.2,172.17.0.3


jmeter pythone二次开发 jmeter二次开发视频_jmeter pythone二次开发_03


  1. 生产的结果文件,日志文件和报表文件在脚本文件test.jmx同一目录下


jmeter pythone二次开发 jmeter二次开发视频_apache_04


  1. 如果压测脚本中使用到了csv数据源文件,需要提前复制到Slaves的/data目录下
注意事项
  1. Master和Slaves需要在同一网段,如果mac电脑Master使用安装在mac电脑中的Jmeter,Slaves使用Docker中的Slaves,需要在启动Slaves时将端口映射出来
    docker run -it -d -p 1099:1099 -p 60001:60001 runcare/jmeter-slave
  2. 执行Master发送脚本时也需要指定server.hostname和server.rmi.localport
进入test.jmx所在目录
result=`date +"%Y%m%d%H%M%S"` && jmeter -n -t test.jmx -l $result.jtl -j $result.log -e -o $result -Djava.rmi.server.hostname=30.208.47.45 -Dserver.rmi.localport=60002 -Dserver_port=1098
Master和Slaves制作附件
  1. Master制作的Dockerfile
# oracle jdk 1.8 备用#FROM runcare/debian-jre1.8# openjdk 1.8FROM runcare/openjdk-jre1.8# 更新版本1MAINTAINER runcare<larrygui@foxmail.com>

ARG JMETER_VERSION="5.1.1"ENV JMETER_HOME /opt/apache-jmeter-$JMETER_VERSION
ENV JMETER_DOWNLOAD_URL  https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz
ENV SSL_DISABLED true

RUNmkdir -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# TODO: plugins (later)# && unzip -oq "/tmp/dependencies/JMeterPlugins-*.zip" -d $JMETER_HOME# Set global PATH such that "jmeter" command is foundENV PATH $PATH:$JMETER_HOME/bin

VOLUME ["/data"]WORKDIR$JMETER_HOMERUN sed 's/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/g' ./bin/jmeter.properties > ./bin/jmeter_temp.propertiesRUNmv ./bin/jmeter_temp.properties ./bin/jmeter.properties
  1. Slaves制作的Dockerfile
# oracle jdk 1.8 备用#FROM runcare/debian-jre1.8# openjdk 1.8FROM runcare/openjdk-jre1.8# 更新版本1MAINTAINER runcare<larrygui@foxmail.com>

ARG JMETER_VERSION="5.1.1"ENV JMETER_HOME /opt/apache-jmeter-$JMETER_VERSION
ENV JMETER_DOWNLOAD_URL  https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-$JMETER_VERSION.tgz
ENV SSL_DISABLED true

RUNmkdir -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# TODO: plugins (later)# && unzip -oq "/tmp/dependencies/JMeterPlugins-*.zip" -d $JMETER_HOME# Set global PATH such that "jmeter" command is foundENV PATH $PATH:$JMETER_HOME/bin

VOLUME ["/data"]WORKDIR$JMETER_HOMEEXPOSE109960001ENTRYPOINT jmeter-server -Dserver.rmi.localport=60001 -Dserver_port=1099 \
            -Jserver.rmi.ssl.disable=$SSL_DISABLED