簡介: 在壓測工作中我們經常遇見對一些關鍵接口需要壓測到很高的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分布式測試環境中有兩個角色:Master和Slaves
- Master節點:向參與的Slaves節點發送測試腳本,並聚合Agent節點的執行結果,部署一台
- Slaves節點:接收並執行Master節點發送過來的測試腳本,並將執行結果返回給Master,可部署多台
部署前置條件,你的機器上已經安裝了Docker
下載Master節點:docker pull runcare/jmeter-master
下載Slaves節點:docker pull runcare/jmeter-slave
分布式壓測使用
- 啟動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
- 准備一個測試腳本文件test.jmx
- 查看一下Slaves機器的IP地址
docker inspect -f '{{ .Name }} => {{ .NetworkSettings.IPAddress }}' $(docker ps -q)
- 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
- 生產的結果文件,日志文件和報表文件在腳本文件test.jmx同一目錄下
- 如果壓測腳本中使用到了csv數據源文件,需要提前復制到Slaves的/data目錄下
注意事項
- Master和Slaves需要在同一網段,如果mac電腦Master使用安裝在mac電腦中的Jmeter,Slaves使用Docker中的Slaves,需要在啟動Slaves時將端口映射出來
docker run -it -d -p 1099:1099 -p 60001:60001 runcare/jmeter-slave
- 執行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制作附件
- Master制作的Dockerfile
# oracle jdk 1.8 備用 #FROM runcare/debian-jre1.8 # openjdk 1.8 FROM runcare/openjdk-jre1.8 # 更新版本1 MAINTAINER 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 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 # TODO: plugins (later) # && unzip -oq "/tmp/dependencies/JMeterPlugins-*.zip" -d $JMETER_HOME # Set global PATH such that "jmeter" command is found ENV PATH $PATH:$JMETER_HOME/bin VOLUME ["/data"] WORKDIR $JMETER_HOME RUN sed 's/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/g' ./bin/jmeter.properties > ./bin/jmeter_temp.properties RUN mv ./bin/jmeter_temp.properties ./bin/jmeter.properties
- Slaves制作的Dockerfile
# oracle jdk 1.8 備用 #FROM runcare/debian-jre1.8 # openjdk 1.8 FROM runcare/openjdk-jre1.8 # 更新版本1 MAINTAINER 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 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 # TODO: plugins (later) # && unzip -oq "/tmp/dependencies/JMeterPlugins-*.zip" -d $JMETER_HOME # Set global PATH such that "jmeter" command is found ENV PATH $PATH:$JMETER_HOME/bin VOLUME ["/data"] WORKDIR $JMETER_HOME EXPOSE 1099 60001 ENTRYPOINT jmeter-server -Dserver.rmi.localport=60001 -Dserver_port=1099 \ -Jserver.rmi.ssl.disable=$SSL_DISABLED