压力测试工具Apache JMeter:8:基于Alpine的JMeter镜像

mac2022-06-30  29

Apache JMeter是一个纯Java开发的用于负载测试或者性能测试的开源软件。这篇文章介绍一下如何使用Alpine基础镜像将JMeter的压测能力进行容器化,并结合具体的示例来演示此镜像从构建到使用的整体过程。

以Alpine为基础构建JMeter镜像

Alpine镜像的特点就是小,在Alpine镜像之上安装jre,并下载JMeter并解压,设定环境变量就完成了JMeter的镜像。

Dockerfile

示例的Dockerfile如下所示 [root@liumiaocn jmeter]# ls Dockerfile [root@liumiaocn jmeter]# cat Dockerfile FROM alpine:3.10.2 ARG VERSION_JMETER="5.1.1" ENV FILENAME_JMETER apache-jmeter-${VERSION_JMETER} ENV HOME_JMETER /usr/local/${FILENAME_JMETER} ENV DOWNLOAD_URL_JMETER https://archive.apache.org/dist/jmeter/binaries/${FILENAME_JMETER}.tgz ENV DOWNLOAD_DIR_LOCAL /tmp/download RUN apk update \ && apk upgrade \ && apk add --update openjdk8-jre curl unzip bash \ && mkdir -p /tmp/download \ && curl -L --silent ${DOWNLOAD_URL_JMETER} > ${DOWNLOAD_DIR_LOCAL}/${FILENAME_JMETER}.tgz \ && mkdir -p /opt ${DOWNLOAD_DIR_LOCAL} \ && tar -xzf ${DOWNLOAD_DIR_LOCAL}/${FILENAME_JMETER}.tgz -C /usr/local \ && rm -rf /var/cache/apk/* \ && rm -rf ${DOWNLOAD_DIR_LOCAL} ENV PATH $PATH:${HOME_JMETER}/bin WORKDIR ${HOME_JMETER}/bin [root@liumiaocn jmeter]#

注:此处为了减小size使用的JRE,但是由于JMeter一部分功能是在keytool基础上的,所以实际使用的时候还是根据情况换成jdk,或者选择相关的apk包进行安装达到要求。

构建JMeter镜像

使用docker build构建JMeter的镜像,输入日志如下所示 [root@liumiaocn jmeter]# docker build -t jmeter:5.1.1 . Sending build context to Docker daemon 2.56 kB Step 1/9 : FROM alpine:3.10.2 ---> 961769676411 Step 2/9 : ARG VERSION_JMETER="5.1.1" ---> Using cache ---> f4f342eab6ba Step 3/9 : ENV FILENAME_JMETER apache-jmeter-${VERSION_JMETER} ---> Using cache ---> f8ca701c741b Step 4/9 : ENV HOME_JMETER /usr/local/${FILENAME_JMETER} ---> Using cache ---> 056cc7e91e6f Step 5/9 : ENV DOWNLOAD_URL_JMETER https://archive.apache.org/dist/jmeter/binaries/${FILENAME_JMETER}.tgz ---> Using cache ---> 49e87f232d91 Step 6/9 : ENV DOWNLOAD_DIR_LOCAL /tmp/download ---> Using cache ---> 58cb1fc2f1f3 Step 7/9 : RUN apk update && apk upgrade && apk add --update openjdk8-jre curl unzip bash && mkdir -p /tmp/download && curl -L --silent ${DOWNLOAD_URL_JMETER} -o ${DOWNLOAD_DIR_LOCAL}/${FILENAME_JMETER}.tgz && mkdir -p /opt ${DOWNLOAD_DIR_LOCAL} && tar -xzf ${DOWNLOAD_DIR_LOCAL}/${FILENAME_JMETER}.tgz -C /usr/local && rm -rf /var/cache/apk/* && rm -rf ${DOWNLOAD_DIR_LOCAL} ---> Running in 908fac559368 fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz v3.10.2-80-g68e4e4a13a [http://dl-cdn.alpinelinux.org/alpine/v3.10/main] v3.10.2-83-g64319a6606 [http://dl-cdn.alpinelinux.org/alpine/v3.10/community] OK: 10336 distinct packages available (1/2) Upgrading libcrypto1.1 (1.1.1c-r0 -> 1.1.1d-r0) (2/2) Upgrading libssl1.1 (1.1.1c-r0 -> 1.1.1d-r0) OK: 6 MiB in 14 packages (1/48) Installing ncurses-terminfo-base (6.1_p20190518-r0) ...省略 (48/48) Installing unzip (6.0-r4) Executing busybox-1.30.1-r2.trigger Executing ca-certificates-20190108-r0.trigger Executing java-common-0.2-r0.trigger OK: 95 MiB in 62 packages ---> 655fe0283c8d Removing intermediate container 908fac559368 Step 8/9 : ENV PATH $PATH:${HOME_JMETER}/bin ---> Running in 9c731c259c57 ---> e32e05b622a9 Removing intermediate container 9c731c259c57 Step 9/9 : WORKDIR ${HOME_JMETER}/bin ---> 45f070d75ce2 Removing intermediate container 958b82eaf6e0 Successfully built 45f070d75ce2 [root@liumiaocn jmeter]# [root@liumiaocn jmeter]# docker images |grep jmeter |grep 5.1.1 jmeter 5.1.1 45f070d75ce2 16 seconds ago 190 MB [root@liumiaocn jmeter]#

测试准备

压力测试应用准备

在本地机器的8088端口使用Docker启动一个Nginx应用(使用其他方式也可),示例如下所示:

liumiaocn:~ liumiao$ docker images |grep nginx |grep latest nginx latest e445ab08b2be 2 months ago 126MB liumiaocn:~ liumiao$ docker run -p 8088:80 -d --name=nginx-test nginx:latest a80fb1a4fc20627891a6bd7394fd79ae9aefb7dc8cf72c12967bc2673a815308 liumiaocn:~ liumiao$

使用curl命令或者直接使用浏览器确认nginx已正常运行

liumiaocn:~ liumiao$ curl http://localhost:8088/ <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> liumiaocn:~ liumiao$

准备jmx文件

jmx文件信息如下所示

liumiaocn:data liumiao$ ls jmeter-nongui-test.jmx liumiaocn:data liumiao$ cat jmeter-nongui-test.jmx <?xml version="1.0" encoding="UTF-8"?> <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.1.1 r1855137"> <hashTree> <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="测试计划" enabled="true"> <stringProp name="TestPlan.comments"></stringProp> <boolProp name="TestPlan.functional_mode">false</boolProp> <boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp> <boolProp name="TestPlan.serialize_threadgroups">false</boolProp> <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="TestPlan.user_define_classpath"></stringProp> </TestPlan> <hashTree> <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="线程组" enabled="true"> <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="循环控制器" enabled="true"> <boolProp name="LoopController.continue_forever">false</boolProp> <stringProp name="LoopController.loops">10</stringProp> </elementProp> <stringProp name="ThreadGroup.num_threads">100</stringProp> <stringProp name="ThreadGroup.ramp_time">1</stringProp> <boolProp name="ThreadGroup.scheduler">false</boolProp> <stringProp name="ThreadGroup.duration"></stringProp> <stringProp name="ThreadGroup.delay"></stringProp> </ThreadGroup> <hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP请求" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="用户定义的变量" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">192.168.31.242</stringProp> <stringProp name="HTTPSampler.port">8088</stringProp> <stringProp name="HTTPSampler.protocol">http</stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/</stringProp> <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.follow_redirects">true</boolProp> <boolProp name="HTTPSampler.auto_redirects">false</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> <stringProp name="HTTPSampler.connect_timeout"></stringProp> <stringProp name="HTTPSampler.response_timeout"></stringProp> </HTTPSamplerProxy> <hashTree/> </hashTree> </hashTree> </hashTree> </jmeterTestPlan> liumiaocn:data liumiao$

注:关于此jmx的生成步骤和说明请参看

https://liumiaocn.blog.csdn.net/article/details/101904948

注意事项:前面示例中关于本地Web应用的压测,hostname设定的为localhost,但是由于jmeter在容器中运行,此localhost不同于彼localhost,所以此处改为了IP(192.168.31.242),请实际验证时修改为自己的IP。

执行测试

启动容器&确认版本

liumiaocn:tmp liumiao$ docker run -it -v $(pwd)/data:/data jmeter:5.1.1 sh /usr/local/apache-jmeter-5.1.1/bin # cd /data /data # ls jmeter-nongui-test.jmx /data # which jmeter /usr/local/apache-jmeter-5.1.1/bin/jmeter /data # jmeter -v _ ____ _ ____ _ _ _____ _ __ __ _____ _____ _____ ____ / \ | _ \ / \ / ___| | | | ____| | | \/ | ____|_ _| ____| _ \ / _ \ | |_) / _ \| | | |_| | _| _ | | |\/| | _| | | | _| | |_) | / ___ \| __/ ___ \ |___| _ | |___ | |_| | | | | |___ | | | |___| _ < /_/ \_\_| /_/ \_\____|_| |_|_____| \___/|_| |_|_____| |_| |_____|_| \_\ 5.1.1 r1855137 Copyright (c) 1999-2019 The Apache Software Foundation /data #

执行测试并生成结果

/data # jmeter -n -t jmeter-nongui-test.jmx -l result.jtl -e -o jmeter-nongui-rpt Creating summariser <summary> Created the tree successfully using jmeter-nongui-test.jmx Starting the test @ Wed Oct 02 07:39:06 GMT 2019 (1570001946517) Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445 summary = 1000 in 00:00:02 = 538.5/s Avg: 55 Min: 2 Max: 393 Err: 0 (0.00%) Tidying up ... @ Wed Oct 02 07:39:09 GMT 2019 (1570001949228) ... end of run /data #

压测报告确认

淼叔 认证博客专家 神经网络 TensorFlow NLP 资深架构师,PMP、OCP、CSM、HPE University讲师,EXIN DevOps Professional与DevOps Master认证讲师,曾担任HPE GD China DevOps & Agile Leader,帮助企业级客户提供DevOps咨询培训以及实施指导。熟悉通信和金融领域,有超过十年金融外汇行业的架构设计、开发、维护经验,在十几年的IT从业生涯中拥有了软件开发设计领域接近全生命周期的经验和知识积累,著有企业级DevOps技术与工具实战。
最新回复(0)