赞
踩
1)压测不同的协议和应用
2)使用场景及优点
强制依赖: JDK
官方下载地址: jmeter.apache.org/download_jm…
官方文档地址: jmeter.apache.org/usermanual/…
bin目录: 核心可执行文件以及核心配置文件
lib目录: 核心的依赖包
方式一: 控制台修改(临时有效)
menu -> options -> choose language
方式二: 配置文件修改(永久有效)
JMeter bin目录 -> jmeter.properties
复制代码
@RestController @RequestMapping(value = "userController") public class UserController { @GetMapping(value = "getUserList") public List<String> getUserList() { return Arrays.asList("tom","marry","jack"); } @PostMapping(value = "login") public Map<String,Object> login(String name,String pwd){ Map<String,Object> map = new HashMap<>(); map.put("name",name); if ("123".equals(pwd)){ map.put("status",0); }else{ map.put("status",-1); } return map; } }
1)创建一个setup线程组
2)设置setup线程组的名称以及请求线程数、请求时间、请求循环次数
3)创建一个http请求
4)编写http请求的url
5)添加察看结果树
6)设置结果树名称并运行该线程组、查看结果树
1)线程组Thread Group(一个线程组里可以添加多个取样器)
2)取样器Sampler(以http请求为例)
3)监听器Listener(以察看结果树为例)
1)给http请求添加响应断言
2)断言结果监听器
断言失败,查看结果树任务,结果颜色标红(通过结果树里面双击不通过的记录,可以看到错误信息)
3)每个sampler下面可以加单独的结果树,然后同时加多个断言,最外层可以加个结果树进行汇总
新增聚合报告
复制代码
<?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> <!-- 10人线程组 --> <SetupThreadGroup guiclass="SetupThreadGroupGui" testclass="SetupThreadGroup" testname="10人线程组" enabled="true"> <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true"> <boolProp name="LoopController.continue_forever">false</boolProp> <stringProp name="LoopController.loops">1</stringProp> </elementProp> <stringProp name="ThreadGroup.num_threads">10</stringProp> <stringProp name="ThreadGroup.ramp_time">10</stringProp> <boolProp name="ThreadGroup.scheduler">false</boolProp> <stringProp name="ThreadGroup.duration"></stringProp> <stringProp name="ThreadGroup.delay"></stringProp> </SetupThreadGroup> <hashTree> <!-- HTTP取样器 --> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="获取用户列表" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">127.0.0.1</stringProp> <stringProp name="HTTPSampler.port">8080</stringProp> <stringProp name="HTTPSampler.protocol"></stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">/userController/getUserList</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> <!-- 响应断言 --> <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="用户列表是否包含jack" enabled="true"> <collectionProp name="Asserion.test_strings"> <stringProp name="3254239">jack</stringProp> </collectionProp> <stringProp name="Assertion.custom_message">jack is null</stringProp> <stringProp name="Assertion.test_field">Assertion.response_data</stringProp> <boolProp name="Assertion.assume_success">false</boolProp> <intProp name="Assertion.test_type">2</intProp> </ResponseAssertion> <hashTree/> <!-- 结果树 --> <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="用户列表结果树" enabled="true"> <boolProp name="ResultCollector.error_logging">false</boolProp> <objProp> <name>saveConfig</name> <value class="SampleSaveConfiguration"> <time>true</time> <latency>true</latency> <timestamp>true</timestamp> <success>true</success> <label>true</label> <code>true</code> <message>true</message> <threadName>true</threadName> <dataType>true</dataType> <encoding>false</encoding> <assertions>true</assertions> <subresults>true</subresults> <responseData>false</responseData> <samplerData>false</samplerData> <xml>false</xml> <fieldNames>true</fieldNames> <responseHeaders>false</responseHeaders> <requestHeaders>false</requestHeaders> <responseDataOnError>false</responseDataOnError> <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage> <assertionsResultsToSave>0</assertionsResultsToSave> <bytes>true</bytes> <sentBytes>true</sentBytes> <url>true</url> <threadCounts>true</threadCounts> <idleTime>true</idleTime> <connectTime>true</connectTime> </value> </objProp> <stringProp name="filename"></stringProp> </ResultCollector> <hashTree/> <!-- 聚合报告 --> <ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="用户列表聚合报告" enabled="true"> <boolProp name="ResultCollector.error_logging">false</boolProp> <objProp> <name>saveConfig</name> <value class="SampleSaveConfiguration"> <time>true</time> <latency>true</latency> <timestamp>true</timestamp> <success>true</success> <label>true</label> <code>true</code> <message>true</message> <threadName>true</threadName> <dataType>true</dataType> <encoding>false</encoding> <assertions>true</assertions> <subresults>true</subresults> <responseData>false</responseData> <samplerData>false</samplerData> <xml>false</xml> <fieldNames>true</fieldNames> <responseHeaders>false</responseHeaders> <requestHeaders>false</requestHeaders> <responseDataOnError>false</responseDataOnError> <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage> <assertionsResultsToSave>0</assertionsResultsToSave> <bytes>true</bytes> <sentBytes>true</sentBytes> <url>true</url> <threadCounts>true</threadCounts> <idleTime>true</idleTime> <connectTime>true</connectTime> </value> </objProp> <stringProp name="filename"></stringProp> </ResultCollector> <hashTree/> </hashTree> <!-- 全局结果树 --> <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="获取用户列表结果树" enabled="true"> <boolProp name="ResultCollector.error_logging">false</boolProp> <objProp> <name>saveConfig</name> <value class="SampleSaveConfiguration"> <time>true</time> <latency>true</latency> <timestamp>true</timestamp> <success>true</success> <label>true</label> <code>true</code> <message>true</message> <threadName>true</threadName> <dataType>true</dataType> <encoding>false</encoding> <assertions>true</assertions> <subresults>true</subresults> <responseData>false</responseData> <samplerData>false</samplerData> <xml>false</xml> <fieldNames>true</fieldNames> <responseHeaders>false</responseHeaders> <requestHeaders>false</requestHeaders> <responseDataOnError>false</responseDataOnError> <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage> <assertionsResultsToSave>0</assertionsResultsToSave> <bytes>true</bytes> <sentBytes>true</sentBytes> <url>true</url> <threadCounts>true</threadCounts> <idleTime>true</idleTime> <connectTime>true</connectTime> </value> </objProp> <stringProp name="filename"></stringProp> </ResultCollector> <hashTree/> </hashTree> </hashTree> </hashTree> </jmeterTestPlan>
1)线程组 -> add -> Config Element(配置原件)-> User Definde Variable(用户定义的变量)
2)编写测试接口
复制代码
@RequestMapping(value = "info") public List<String> info(String name){ List<String> userList = new ArrayList<>(); userList.add(name); userList.add(String.valueOf(name.length())); return userList; }
3)引用方式${XXX},在接口中变量中使用
4)原始查看结果树和非原生查看(基础按钮)
1)线程组->add -> Config Element(配置原件)-> CSV data set config (CSV数据文件设置)
2)实战操作jmeter读取txt文本文件里面的参数进行压测
复制代码
user1 user2 user3
3)实战操作jmeter读取csv文本文件里面的参数进行压测
复制代码
user1 user2 user3
1)修改接口
复制代码
@RequestMapping(value = "info") public List<String> info(String name,String pwd){ List<String> userList = new ArrayList<>(); userList.add(name); userList.add(pwd); return userList; }
2)修改txt文件
复制代码
user1|pwd1 user2|pwd2 user3|pwd3
3)修改cvs文件
复制代码
user1 pwd1 user2 pwd2 user3 pwd3
1)Thread Group -> add -> sampler -> jdbc request
2)jar包添加 mysql-connector-java-8.0.15.jar
3)JDBC request->add -> config element -> JDBC connection configuration
核心配置:
1)预处理查询语句
2)预处理更新语句
3)Thread Group -> add -> sampler -> debug sampler
参数说明(sql语句结尾不要加分号):
Jmeter分布式压测原理:
命令行执行mvn打包命令:
复制代码
mvn package
命令行执行jar包:
复制代码
java -jar cyan-jmeter-0.0.1-SNAPSHOT.jar
官方下载地址: www.oracle.com/technetwork…
将下载好的文件上传至服务器,并执行解压命令:
复制代码
$ tar -zxvf jdk-8u201-linux-x64.tar.gz -C /usr/local/ $ cd /usr/local/ $ ln -s jdk1.8.0_201/ jdk $ cd jdk/ $ pwd /usr/local/jdk
配置jdk环境变量:
复制代码
$ vim /etc/profile # 进入后在该文件末尾添加如下配置 JAVA_HOME=/usr/local/jdk export JAVA_HOME CLASSPATH=.:$JAVA_HOME/lib export CLASSPATH PATH=$PATH:$JAVA_HOME/bin:$CLASSPATH export PATH # :wq保存并退出后重启该配置文件 $ source /etc/profile
验证是否安装成功:
复制代码
$ java $ javac $ java -version
1)将打包好的jar上传至云服务器
注意点:
** 2)linux上运行jar包**
复制代码
java -jar cyan-jmeter-0.0.1-SNAPSHOT.jar
3)守护进程运行jar包
复制代码
nohup java -jar cyan-jmeter-0.0.1-SNAPSHOT.jar &
官方下载地址: jmeter.apache.org/download_jm…
将下载好的文件上传至服务器,并执行解压命令:
复制代码
$ tar -zxvf apache-jmeter-5.1.1.tgz -C /usr/local/ $ cd /usr/local/ $ ln -s apache-jmeter-5.1.1/ jmeter $ cd jmeter/ $ pwd /usr/local/jmeter
非GUI界面,压测参数讲解:
复制代码
-h 帮助 -n 非GUI模式 -t 指定要运行的JMeter测试脚本文件 -l 记录结果的文件,每次运行之前要确保之前没有运行过,即xxx.jtl不存在,不然报错) -r Jmter.properties文件remote_hosts属性指定的所有远程服务器中进行测试 -e 在脚本运行结束后生成html报告 -o 用于存放html报告的目录(目录要为空,不然报错)
官方配置参数详解地址: jmeter.apache.org/usermanual/…
测试准备: 将本地的测试计划(jmeterTest.jmx文件)上传至云服务器
官方推荐命令:
复制代码
jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
在云服务器上执行如下命令进行压测:
复制代码
$ ./jmeter -n -t /usr/local/jmeter/bin/jmeterTest.jmx -l result.jtl -e -o /usr/local/jmeter/bin/temp Creating summariser <summary> Created the tree successfully using /usr/local/jmeter/bin/jmeterTest.jmx Starting the test @ Wed Mar 04 13:01:17 CST 2020 (1583298077099) Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445 summary = 10 in 00:00:05 = 2.2/s Avg: 13 Min: 9 Max: 39 Err: 0 (0.00%) Tidying up ... @ Wed Mar 04 13:01:22 CST 2020 (1583298082100) ... end of run
查看准备: 将压测生成的result.jtl文件下载到本地
可以通过打开jmeter,新建线程组->summary report->浏览文件进行查看:
JMeter压测减少资源使用的一些建议:
官方推荐: jmeter.apache.org/usermanual/…
把Jmtere压测结果转换为Html:
复制代码
$ ./jmeter -n -t /usr/local/jmeter/bin/jmeterTest.jmx -l result.jtl -e -o /usr/local/jmeter/bin/temp
转换后目录结构如下:
复制代码
[root@cyan temp]# ll total 24 drwxr-xr-x 5 root root 4096 Mar 4 13:01 content -rw-r--r-- 1 root root 9463 Mar 4 13:01 index.html drwxr-xr-x 5 root root 4096 Mar 4 13:01 sbadmin2-1.0.7 -rw-r--r-- 1 root root 874 Mar 4 13:01 statistics.json
下载到本机即可查看(index.html)
压测报告html里面Dashboard的核心指标说明:
1)Test and Report informations
2)APDEX(Application performance Index)
3)Requests Summary
4)Statistics 统计数据
压测报告html里面Charts的核心指标说明:
1)Over Time(随时间变化)
2)Throughput(吞吐量)
3)Response Times(响应时间)
1)压测注意事项
官网地址 jmeter.apache.org/usermanual/…
压测注意事项: 一定要用内网IP,不用公网IP(有带宽限制),用ping去检查
2)专业名字
3)网络拓扑图:
4)远程拷贝(内网地址):
复制代码
scp -r /usr/local/software/jdk-8u141-linux-x64.tar.gz root@172.18.230.233:/usr/local/software scp -r /usr/local/software/jmeter/apache-jmeter-4.0.tgz root@172.18.230.233:/usr/local/software/jmeter
5)启动
复制代码
./jmeter-server nohup ./jmeter-server &
6)检查启动是否成功
复制代码
ps -ef|grep jmeter-server ps aux|grep jmeter-server
1)内存不足
复制代码
$ cd /usr/local/jmeter/ $ ./bin/jmeter Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c0000000, 1073741824, 0) failed; error='Cannot allocate memory' (errno=12) # # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 1073741824 bytes for committing reserved memory. # An error report file with more information is saved as: # /usr/local/jmeter/apache-jmeter-4.0/bin/hs_err_pid5855.log
解决方案:编辑jmeter文件,修改启动堆内存和最大堆内存
复制代码
$ vim bin/jmeter # 修改如下启动堆内存和最大堆内存 : "${HEAP:="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"}"
2)拥有rmi over ssl的有效秘钥库,或者禁用了ssl
复制代码
$ ./bin/jmeter-server Server failed to start: java.rmi.server.ExportException: Listen failed on port: 0; nested exception is: java.io.FileNotFoundException: rmi_keystore.jks (No such file or directory) An error occurred: Listen failed on port: 0; nested exception is: java.io.FileNotFoundException: rmi_keystore.jks (No such file or directory)
解决方案:禁用SSL
复制代码
$ vim bin/jmeter.properties # 禁用SSL server.rmi.ssl.disable=true
再次启动jmeter:
复制代码
$ ./bin/jmeter-server Created remote object: UnicastServerRef2 [liveRef: [endpoint:[172.17.156.214:41187](local),objID:[3ff15d6a:170a80f2a47:-7fff, 3197885818151024044]]]
1)压测修改master节点信息
复制代码
$ vim bin/jmeter.properties # remote_hosts值是slave机器的ip+端口号,如果有多个,用逗号分隔 # remote_hosts=127.0.0.1 remote_hosts=192.168.1.25:8899,192.168.1.26:8899 server.rmi.ssl.disable=true # server_port=1099
2)压测修改slave节点信息
复制代码
server_port=8899 server.rmi.ssl.disable=true
3)启动slave机器,注意要同个网段,ip地址用内网ip
复制代码
$ ./bin/jmeter-server
4)压测
5)本地非GUI分布式压测(-r)
复制代码
$ ./jmeter -n -t /usr/local/jmeter/bin/jmeterTest.jmx -r -l result.jtl -e -o /usr/local/jmeter/bin/temp Creating summariser <summary> Created the tree successfully using /Users/jack/Desktop/remote.jmx Configuring remote engine: 172.20.10.3:8899 Using local port: 8899 Configuring remote engine: 172.20.10.11:8899 Starting remote engines Starting the test @ Thu Mar 29 23:21:13 CST 2018 (1522336873931) Remote engines have been started Waiting for possible Shutdown/StopTestNow/Heapdump message on port 4445 summary = 4 in 00:00:22 = 0.2/s Avg: 5582 Min: 94 Max: 21006 Err: 1 (25.00%) Tidying up remote @ Thu Mar 29 23:21:36 CST 2018 (1522336896842) ... end of run ```
自动化测试相关教程推荐:
2023最新自动化测试自学教程新手小白26天入门最详细教程,目前已有300多人通过学习这套教程入职大厂!!_哔哩哔哩_bilibili
2023最新合集Python自动化测试开发框架【全栈/实战/教程】合集精华,学完年薪40W+_哔哩哔哩_bilibili
测试开发相关教程推荐
2023全网最牛,字节测试开发大佬现场教学,从零开始教你成为年薪百万的测试开发工程师_哔哩哔哩_bilibili
postman/jmeter/fiddler测试工具类教程推荐
讲的最详细JMeter接口测试/接口自动化测试项目实战合集教程,学jmeter接口测试一套教程就够了!!_哔哩哔哩_bilibili
2023自学fiddler抓包,请一定要看完【如何1天学会fiddler抓包】的全网最详细视频教程!!_哔哩哔哩_bilibili
2023全网封神,B站讲的最详细的Postman接口测试实战教学,小白都能学会_哔哩哔哩_bilibili
如果对你有帮助的话,点个赞收个藏,给作者一个鼓励。也方便你下次能够快速查找。
如有不懂还要咨询下方小卡片,博主也希望和志同道合的测试人员一起学习进步
在适当的年龄,选择适当的岗位,尽量去发挥好自己的优势。
我的自动化测试开发之路,一路走来都离不每个阶段的计划,因为自己喜欢规划和总结,
测试开发视频教程、学习笔记领取传送门!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。