JMeter
1.常用压力测试工具对比
a. loadrunner
性能稳定、压测结果及细粒大,可以自定义脚本进行压测,但是太过于重大、功能比较繁多(国企或专业的测试团队)
b. apache ab(单接口压测最方便,传统互联网公司)
模拟多线程并发请求,ab命令对发出负载计算机要求很低,既不会占用太多的内存,但是却会给目标服务器造成巨大的负载,简单DDOS攻击等
c. webbench
webbench首先fork出多个子进程,每个子进程都循环做web访问测试,子进程把访问的结果pipe告诉父进程,父进程做最终的统计结果.
2.Jmeter基本介绍和使用场景
a.Ability to load and performance test many different applications/server/protocol types:
Web - HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, …)
SOAP / REST Webservices
FTP
Database via JDBC
LDAP
Message-oriented middleware (MOM) via JMS
Mail - SMTP(S), POP3(S) and IMAP(S)
Native commands or shell scripts
TCP
Java Objects
b.使用场景及优点
功能测试
压力测试
分布式压力测试
纯java开发
上手容易、高性能
提供测试数据分析
各种报表数据图形展示
3. 本地快速安装jmeter4.x
简介: GUI图形界面的安装
a.安装x-windows
yum groupinstall 'X Window System' -y yum groupinstall "GNOME Desktop" -y //要开启3D systemctl set-default multi-user.target //设置成命令模式 systemctl set-default graphical.target //设置成图形模式 startx
CentOS 7 切换图形界面和文本界面
https://www.ifshow.com/centos-7-switching-graphical-and-text-interface/
b. 需要安装jdk8,9 或10(不建议单独安装jre)
[root@node2 ~]# cat /etc/profile.d/jdk.sh export JAVA_HOME=/home/jdk1.8.0_152 export PATH=$JAVA_HOME/bin:$PATH
c.安装jmeter
[root@node2 ~]# wget http://mirrors.hust.edu.cn/apache//jmeter/binaries/apache-jmeter-4.0.tgz [root@node2 ~]# tar xf apache-jmeter-4.0.tgz [root@node2 ~]# cd apache-jmeter-4.0/bin [root@node2 bin]# ./jmeter
d. 设置Jmeter环境变量
[root@node2 ~]# cat /etc/profile.d/jmeter.sh export JMETER=/root/apache-jmeter-4.0 export CLASSPATH=$JMETER/lib/ext/ApacheJMeter_core.jar:$JMETER/lib/jorphan.jar:$CLASSPATH export PATH=$JMETER/bin/:$PATH [root@node2 ~]# source /etc/profile.d/jmeter.sh [root@node2 ~]# jmeter -v Linux下运行Java项目时,出现No X11 DISPLAY variable was set, but this program performed an operation which requires it.的问题解决 在~/.bashrc环境变量文件最下方加入: export DISPLAY=:0.0 然后,刷新环境变量以使其生效: source ~/.bashrc
4. jmeter目录文件
[root@node2 apache-jmeter-4.0]# ll bin 执行文件、包含配置 windows: jmeter.bat linux: jmeter jmeter-server:分布式压测启动文件 jmeter.properties: 核心配置文件 extras 插件拓展 lib 核心依赖包 junit 单元测试包
5.Jmeter语言版本中英文切换
a. 控制台修改 menu --> options --> choose language(临时悠)
b. 配置文件修改(永久)
bin目录 --> jmeter.properties(默认是#language=en,修改为language=zh)
6.使用SpringBoot 2.0快速编写API测试接口
描述:使用java的框架springBoot快速编写几个API接口测试
http://spring.io/guides/gs/spring-boot/
接口列表:
a. 模拟GET请求,用户列表接口
b. 模拟POST请求,用户登录接口
http://localhost:8080/users
7.创建Jmeter测试计划,快速压测一个接口
a.创建一个测试计划
teat plan --> add --> threads(users) --> setup Thread Group
Name: 10 threads
Number os threads: 10 线程数
ramp-up period(in seconds): 10 (10秒)
loop count: 1 循环次数
线程数: 虚拟用户数, 一个虚拟用户占用一个进程或线程(模拟多少个用户请求)
准备时长(Ramp-Up Period(in seconds))
全部线程启动时长,比如100个线程,20秒,则表示20秒内100个线程都要启动完成,每秒启动5个线程
循环次数:每个线程发送的次数,假如值为5,100个线程,则会发送500次,可以勾选永远循环
右上角的00:00:00 是压测的执行时间(压测计划所消耗的时间)
右上角的叹号是日志
0/0 是并发的一个数量
b.创建一个请求
10 threads --> add --> sampler --> HTTP Request
protocol: 默认是http(可写https)
server Name or ip: 127.0.0.1
method: get #可以使用Post,path:/login, 输入账号密码parameters: name,password , include equals
port: 8080
path: /users
名称:采样器名称
注释:对这个采样器的描述
web服务器:
默认协议是http
默认端口是80
服务器名称或Ip: 请求的目标服务器名称或IP地址
路径:服务器URL
Use multipart/from-data for HTTP POST: 当发送POST请求时,使用use multipart/from-data方法发送,默认不选中
follow redirects: 有些返回302重定向
use keepalive: 保持连接
c.创建一个查看结果树(发送请求对应的结果)
10 threads --> add --> listener --> view results tree
summary
分析:可以同时调用登录和用户信息接口,实现接口的联动性
8.Jmeter的断言基本使用
jmeter中有个元件叫做断言(Assertion),它的作用和loadrunner中的检查点类似;
用于检查测试中得到的响应数据等是否符合预期,用以保证性能测试过程中的数据交互与预期一致。
使用断言的目的:在request的返回层面增加一层判断机制;因为request成功了,并不代表结果一定正确。
http requests --> add --> assertions --> response assertion
name: include 200
apply to : main sample only(一个接口触发一个请求,如果一个接口联动其他选main sample and sub-samples)
field test(要测试的响应字段,发一个请求过去,会有请求头,相关的响应信息)
text response(响应文本): 返回的信息
response code: http代码,如200
document: 如一些pdf,这个断言比较消耗性能
Pattern Matching Rules(匹配规则)
contains: 包含的范围,如包含jack这个字段
matches: 匹配不区分大小写
equals: 区分大小写
substring: 子字符串
Pattern to test: 如add --> 200 匹配200
custom failuer message: 失败返回的信息
查看结果树中: text可以双击对应的报错,可以通过响应代码、响应信息等等共同来判断
每个sample下面可以加单独树,然后同时加多个断言,最外层可以加结果树进行汇总
9.Jmeter实战之压测结果聚合报告分析
描述:聚合报告是辱没结果时,会有响应时间,请求大小,吞吐量等
http request --> add --> listener --> aggregate report
label: sample的名称
samples: 总共发送的请求数,如10个用户循环10次,也就是100
average: 平均响应时间,单位是毫秒
median: 平均时间中位数(大多数用户的一个响应时间),有时随着负载升得越来越高,它的中位数会变
90%line: 90%用户的响应时间不会越过这个值如54毫秒
95%line: 95%用户的响应时间不会越过这个值如368毫秒
99%line: 99%用户的响应时间不会越过这个值如504毫秒
min: 最小响应时间如3毫秒
max: 最大响应时间如438毫秒
error%:
throughput: 每秒请求数,类似于qps,qps不能长时,基本上是瓶颈,并长上升时,会下降
received KB/s: 接收的字节数
sent KB/s: 发送的字节数
10.Jmeter压测脚本JMX讲解
测试计划 <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true"> </TestPlan> 线程组 <SetupThreadGroup guiclass="SetupThreadGroupGui" testclass="SetupThreadGroup" testname="user_api" enabled="true"> </SetupThreadGroup> 测试名称 testname="user_api" 循环次数 <stringProp name="LoopController.loops">2</stringProp> 并发数(模拟用户数) <stringProp name="ThreadGroup.num_threads">30</stringProp> 并发时间 <stringProp name="ThreadGroup.ramp_time">5</stringProp> http request <stringProp name="HTTPSampler.domain">172.16.100.8</stringProp> <stringProp name="HTTPSampler.port">80</stringProp> <stringProp name="HTTPSampler.protocol"></stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path"></stringProp> <stringProp name="HTTPSampler.method">GET</stringProp> 响应断言 <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true"> <stringProp name="49586">200</stringProp> <stringProp name="Assertion.custom_message"></stringProp> #失败后的信息 <intProp name="Assertion.test_type">1</intProp> #test_type对应类型,如包含、匹配等 结果树 <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true"> 聚合报告 <ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="User Aggregate Report" enabled="true">
11.Jmeter用户自定义变量实战
使用原因:很多变量在全局中都有使用,或者测试数据更改,可以在一处定义,四处使用,如服务器
a. 线程组 --> add --> config element(配置条件) --> user definde variable(用户定义的变量)
b. 引用方式$(XXX),在接口中变量使用,在path中也可以使用
c. 原始查看结果和非原生查看(基础按钮)
注意:只执行某一个时,threads组 --> 右击start(导航的三角是执行所有的)
12. Jmeter实战之CSV可变参数压测
描述:压力测试时,不会单用户去测试,参数要不段的变化,如果缓存命中就没意义,CSV就是解决这个问题,可以通过读取文本中很多用户数据
a. 线程组 --> add --> config elemnet(配置原件) --> CSV data set config(CSV数据文件设置)
[root@node1 ~]# cat user_info.txt #csv一般以空格 user11|pwd11 user22|pwd22 user33|pwd33 选项 filename: csv文件 file encoding: 是否编码 variable names: 变量名称,是引用时${}的名称 sharing mode: all threads(变量是否在所有场景中引用) delimiter: 使用的分隔符,如使用txt时可以使用" | “分隔
b.CSV文件多参数使用
13. 压测实战之JDBC request压测Mysql
a.添加线程组:test plan --> add --> threads(user) --> threads group(setup and teardown作为前置后后置处理)
b. thread group --> add --> sampler --> jdbc request
c. jar 包添加 mysql-connector-java-5.1.30.jar (可以在test plan最下处加add directory or jar to classpath)
d.JDBC connection Configuration配置
JDBC request --> add --> config element --> JDBC connection configuration
注:variable name bound to pool要与jdbc request中的一致
核心配置
Max number of connection:最大连接数(mysql一般是3000-4000)
MAX wait : 最大等待时间
Auto Commit: 是否自动提交事务
DataBase URL: 数据库连接地址 jdbc:mysql://172.16.100.8:3306/blog
JDBC Driver Class: 数据库驱动,选择对应的mysql
username: 数据库用户名
password: 数据库密码
14.实战之request压测Mysql, select语句
a. debug sampler使用(调试采样器)
thread group --> add --> sampler --> debug sampler (variable names sql and result variables names)
在view result tree中的debug sampler中的respone data中的name_#是对应以下handle results
b.参数(sql结尾不要加';')
- variable name of pool declared in JDBC connection configuration(和配置文件同名)
- Query Type 查询类型
- parameter values 参数值
- parameter types 参数类型
- variable names sql 执行结果变量名 #这两个参数主要用于debug sampler
- result variable names 所有结果当做一个对象存储
- query timeouts 查询超时时间
- handle results 处理结果集
Query type
select statement 查询语句
update statement 更新语句
callable statement 存储过程
prepared select statement 预编译的查询语句,查询时可能有?,防止sql注入
prepared update statement
commit 事务提交
rollback
autocommit(false)
debug sampler
15. 分布式压测介绍
- 普通压测试: 单台机可以对目标机器产生压力比较小,并发数特别高时,受限因素包括CPU、网络、IO等
- 分布式压测试: 利用多台机器向目标机器产生压力,模拟几万用户并发访问
注:在网站安全,API接口要做一个DDOS的流量阀值的限制,每个Ip限制访问次数
原理
- 总控制机器的节点master(修改remote_host配置),其他产生压力的机器叫"肉鸡" server(机器要在同一个网段,且安装相应的Jdk,使用RMI通讯)
[root@node2 ~]# grep remote_hosts apache-jmeter-4.0/bin/jmeter.properties remote_hosts=172.16.100.100:1109,172.16.100.101:1109,172.16.100.102:1109
- master会把压测脚本送到server上面
- 执行时,其他节点server上只需要把jmeter-server打开,不用启动jmeter
- 结束后,server会把压测数据回传给master,然后master汇总输出报告
配置准备
三个角色:master slave target(master控制slave向target进行压测,slave再收集信息返回给master)
压力测试注意事项
- 系统上的防火墙被关闭或正确的端口被打开
- 所有的客户端都在同一个子网上
- 如果使用192.x.x.x或10.x.x.x IP地址,则服务器位于同一子网中,如果服务器不使用192.xx或10.xx的IP地址,则不会有任何问题
- 确保jmeter可以访问服务
- 确保所有系统上使用相同版本的Jmeter和java,混合版本将无法正常工作
- 您已经为RMI设置SSL或将其禁用
阿里云jmeter压测常见问题处理
a.there is insufficient memory for th java runtime environment to continue(当启动jmeter-server时,内存不足)
分析:内存低,减小应用启动的JVM内存 vim jmeter "${HEAP:="-Xms124m -Xmx124m -XX:MAXMetaspaceSize=256m"}" #把1g修改成124m,第一个是初始的堆内存,第二个是最大的堆内存,第三个是原数据最大的保存区域
b. rmi_keystore.jks(no such file or directory) 是jmeter远程调用时需要一个rmi的密钥
解决:禁用SSL,在jmeter.property中server.rmi.ssl.diable 改为 true,表示禁用
c. server failed to start: java rmi.remoteexception: cannot start. unable to get local host ip address
vim /etc/hosts ip 机器名
d.master机器启动后会拷贝jmx文件到slave机器, 所以不要在每台slave上传一wwvjmx,只需要在master上有一份即可,
如果使用csv进行参数化,则需要把参数文件在每台slave上拷贝一份且路径需要设置成一样的 总样本数 = 线程数 * 循环次数 * 执行机总数
e.连接失败原因排查
- jmeter-server是否启动
- 是否联网
- ping 服务器IP是否畅通
- telnet Ip port
- 检查服务器的防火墙是否关闭
- 云上的策略是否正常
f.could not find apachejmeter_core.jar
解决:在agent机器上安装jdk,并设置环境变量
g.bad call to remote host
解决:检查控制机器上的Jmeter-server有没启动,或者remte_hosts是否配置正确
分布式压力测试操作
a.在master上添加slave节点,修改jmeter.properties(修改完后重新启动)
[root@node2 ~]# vim apache-jmeter-4.0/bin/jmeter.properties remote_hosts=192.168.201.123:8899,192.168.201.125:8899 server_port=8899 erver.rmi.ssl.disable=true #禁用ssl
b.配置slaves
vim apache-jmeter-4.0/bin/jmeter.properties remote_hosts=127.0.0.1 server_port=8899 erver.rmi.ssl.disable=true
c.先启动slaves(关闭防火墙或开通相关端口)
./jmeter-server (成功后显示:created remote object)
d. 在master远程执行测试
- 制作测试计划 - run --> remote start/remote stop
e. 使用命令行远程压力测试(-r远程)
jmeter -n -t linus_users_api.jmx -r -l result.jtl -e -o /usr/local/software/jmeter/temp/ResultReport
16. springboot打包,并使用Jar包方式部署
描述:使用图形界面比较消耗性能
打包:mvn package && java -jar target/gs-spring-boot-0.1.0.jar & (G:\jmeter\资料\阿里云部署jar包) nohup java -jar gs-spring-boot-0.1.0.jar & 访问:http://192.168.201.8:8080/users
17.Jmeter非GUI界面
参数: https://jmeter.apache.org/usermanual/get-started.html
-h 帮助 -n 非GUI模式(GUI模式下比较消耗性能) -t 指定要运行的jmeter测试脚本文件 -l 记录结果文件,每次运行之前(要确保之前没有运行过,即xxx.jtl不存在,不然报错) -r jmeter.properties文件中指定所有远程服务器 -e 在脚本运行结束后生成html报告 -o 用于存放html报告的目录(目录要为空,不然报错) jmeter -n -t linus_users_api.jmx -l result.jtl -e -o /usr/local/software/jmeter/temp/ResultReport [root@node2 ~]# jmeter -n -t jmx/user_api.jmx -l result.jtl -e -o jmx/report/ Creating summariser <summary> Created the tree successfully using jmx/user_api.jmx Starting the test @ Thu Jun 07 13:40:09 CST 2018 (1528350009144) Waiting for possible Shutdown/StopTestNow/Heapdump message on port 4445 summary = 12000 in 00:00:17 = 687.2/s Avg: 290 Min: 0 Max: 3435 Err: 0 (0.00%) Tidying up ... @ Thu Jun 07 13:40:27 CST 2018 (1528350027503) ... end of run
压测实战之jtl文件生成和查看
threads group --> add --> listener --> summary report
18.Jmeter压测接口的性能优化
- 使用非GUI模式,jmeter -n -t test.jmx -l result.jtl
- 少使用listener,如果使用-l参数,它们都可以被删除或禁用
- 在加载测试期间不要使用“查看结果树”或“查看结果”表监听器,只能在调试阶段使用它们来测试脚本
- 包含控制器在这里没有帮助,因为它将文件中的所有测试元素添加到测试计划中
- 不要使用功能模式,使用CSV输出而不是XML
- 只保存你需要的数据,尽可能少地使用断言
- 如果测试需要大量数据,可以提前准备好测试数据放到数据文件中,以CSV READ方式读取
- 用内网压测,减少其他带宽压测结果
- 如果压测大流量,尽量用多几个节点以非GUI模式向服务器施压
19.Jmeter压测生成多维度图形化HTML测试报告
[root@node2 ~]# jmeter -n -t jmx/user_api.jmx -l result.jtl -e -o jmx/report/ [root@node2 ~]# cd jmx/report/ [root@node2 report]# ll total 28 drwxr-xr-x. 5 root root 40 Jun 7 13:40 content -rw-r--r--. 1 root root 8986 Jun 7 13:40 index.html -rw-r--r--. 1 root root 15437 Jun 7 13:40 README.TXT drwxr-xr-x. 5 root root 89 Jun 7 13:40 sbadmin2-1.0.7
Jmeter图形化HTML压测报告dashboard
a. test and report information
- source file: jtl文件名
- start time: 压测开始时间
- end time: 压测结束时间
- filter for display: 过滤器
- lable: sampler采样名称
b. APDESX(application performance index)
apdex: 应用程序性能指标,范围在0-1之间,1表示达到所有用户均满意
T(Toleration threshold): 可接受阀值
F(Frustration threshold):失败阀值
c. requests summary
- ok: 成功率
- ko: 失败率
d. statistics 统计数据(核心数据)
- lable: sampler采样器名称
- samples: 请求总数,并发数*循环次数
- KO: 失败次数
- Error: 失败率
- Average: 平均响应时间
- Min: 最小响应时间
- Max: 最大响应时间
- 90th pct: 90%的用户响应时间不会超过这个值(关注这个就可以,因为95%与99%是有极端值的)
如2ms,3ms,4,5,2,6,8,8,3,9,先把整个响应时间排序,90%从小到大,还有10%最大的去掉,如去掉9,然后90%用户都不会超过8
- 95th pct: 95%的用户响应时间不会超过这个值
- 99th pct: 99%的用户响应时间不会超过这个值(存在极端值)
throughtput: request per second吞吐量 qps
received:每秒从服务器接收的数据量
send:每秒发送的数据量
Jmeter图形化HTML压测报告Charts
a. over time(随着时间的变化)
- response time over time: 响应时间变化趋势(一般开头都比较高)
- response time percentiles over time(successful response) : 最大、最小
- active threads over time: 并发用户数趋势(从0开始增长都设置的并发数)
- bytes throughput over time: 每秒接收和请求字节数变化,蓝色表示发送,黄色表示接收(从开始慢慢增长)
- latencies over time: 平均响应延时趋势
- connect time over time: 连接消耗时间趋势(如tcp等三次握手时间)
b.thoughput
- hits per second(excluding embedded resources): 每秒点击次数
- codes per second (excluding embedded resources): 每秒状态码数量
- transactions per second : 每秒事务数,tps , 如转账会涉及事务
- response time vs request: 响应时间和请求数对比
- latency vs request: 延迟时间和请求数对比
c. response times
- response time percentiles: 响应时间百分比
- response time overview: 响应时间概述
- time vs threads: 活跃线程数和响应时间
- response time distribution: 响应时间分布图
20.利用JMeter的录制功能对Web网页进行压力测试
- 新生成一个Test Plan,为它新增一个Thread Group。为这个Thread Group
- 新建一个录制模板
- 配置http test script recorder
- 设置浏览器代理