Jmeter
常用压力测试工具对比
- loadrunner:
性能稳定,压测结果及细粒度大,可以自定义脚本进行压测,但是太过于重大,功能比较繁多
。 - apache ab(单接口压测最方便):
模拟多线程并发请求,ab命令对发出负载的计算机要求很低,既不会占用很多CPU,也不会占用太多的内存,但却会给目标服务器造成巨大的负载, 简单DDOS攻击等
。 - webbench:
webbench首先fork出多个子进程,每个子进程都循环做web访问测试。子进程把访问的结果通过pipe告诉父进程,父进程做最终的统计结果。
压测不同的协议和应用
- 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)
- TCP 等等
使用场景及优点
- 功能测试
- 压力测试
- 分布式压力测试
- 纯 Java 开发
- 上手容易,高性能
- 提供测试数据分析
- 各种报表数据图形展示
GUI 图形界面的安装
- JDK8 或以上
- jmeter-4.0
Jmeter 目录及文件
* bin:核心可执行文件,包含配置
jmeter: mac或者linux启动文件
jmeter.bat: windows启动文件
jmeter-server:mac或者Liunx分布式压测使用的启动文件
jmeter-server.bat:windows分布式压测使用的启动文件
jmeter.properties: 核心配置文件
shutdown.cmd:停止服务
* extras:插件拓展的包
* lib:核心的依赖包
ext:核心包
junit:单元测试包
GUI 菜单栏主要组件
- 添加->threads-> 线程组(控制总体并发)
* 线程数:虚拟用户数。一个虚拟用户占用一个进程或线程。
* 准备时长(Ramp-Up Period(in seconds)):全部线程启动的时长,比如100个线程,20秒,则表示20秒内100个线程都要启动完成,每秒启动5个线程。
* 循环次数:每个线程发送的次数,假如值为5,100个线程,则会发送500次请求,可以勾选永远循环。
- 线程组-> 添加-> Sampler(采样器) -> Http (一个线程组下面可以增加几个 Sampler)
* 名称:采样器名称
* 注释:对这个采样器的描述
* web服务器:默认协议是http、默认端口是80、服务器名称或IP :请求的目标服务器名称或IP地址。
* 路径:服务器URL。
* Use multipart/from-data for HTTP POST :当发送POST请求时,使用Use multipart/from-data 方法发送,默认不选中。
- 查看测试结果
* 线程组->添加->监听器->察看结果树
Jmeter 的断言
每个 sample 下面可以加单独的结果树,然后同时加多个断言,最外层可以加个结果树进行汇总。
- 增加断言: 线程组 -> 添加 -> 断言 -> 响应断言
* apply to(应用范围):
Main sample only: 仅当前父取样器 进行断言,一般一个请求,如果发一个请求会触发多个,则就有sub sample(比较少用)
* 要测试的响应字段:
响应文本:即响应的数据,比如json等文本
响应代码:http的响应状态码,比如200,302,404这些
响应信息:http响应代码对应的响应信息,例如:OK, Found
Response Header: 响应头
* 模式匹配规则:
包括:包含在里面就成功
匹配:响应内容完全匹配,不区分大小写
equals:完全匹配,区分大小写
- 断言结果监听器: 线程组-> 添加 -> 监听器 -> 断言结果
里面的内容是sampler采样器的名称
断言失败,查看结果树任务结果颜色标红(通过结果数里面双击不通过的记录,可以看到错误信息)
聚合报告分析
- 新增聚合报告:线程组-> 添加-> 监听器-> 聚合报告(Aggregate Report)
用户自定义变量
很多变量在全局中都有使用,或者测试数据更改,可以在一处定义,四处使用比如服务器地址。建议每个线程组内定义属于该线程组的变量。
- 线程组->add -> Config Element(配置原件) -> User Definde Variable(用户定义的变量) -> add
ip 192.168.31.230
port 8080
- 引用方式 ${XXX},在接口中变量中使用
${ip}
${port}
CSV 可变参数压测
操作 jmeter 读取 CSV 和 Txt 文本文件里面的参数进行压测。
线程组->add -> Config Element(配置原件)-> CSV data set config (CSV数据文件设置)
CSV 文件多参数使用
如果是多个参数需要同时引用,则在 CSV 数据文件里面设置加多个字段。
# CSV设置
Variabled names(comma-delitited): csv_name,csv_pwd
# 访问路径中引用CSV设置多参数
/info?name=${csv_name}&pwd=${csv_pwd}
# 结果树中查看Request发现参数已被替换成实参
GET http://192.168.31.230:8080/info?name=user11&pwd=pwd11
MySQL 数据库压测
- Thread Group -> add -> sampler -> JDBC request jar 包添加 mysql-connector-java-5.1.30.jar
- JDBC request->add -> config element -> JDBC connection configuration
Max Number of connections : 最大连接数
MAX wait :最大等待时间
Auto Commit: 是否自动提交事务
DataBase URL : 数据库连接地址 jdbc:mysql://127.0.0.1:3306/blog
JDBC Driver Class : 数据库驱动,选择对应的mysql
username:数据库用户名
password:数据库密码
- Debug Sampler 使用(结果树中查看)
Debug Sampler 作用于 variable names 和 result variable names。
Thread Group -> add -> sampler -> debug sampler
- 参数说明
1、variable name of pool declared in JDBC connection configuration(和配置文件同名)
2、Query Type 查询类型
3、parameter values 参数值
4、parameter types 参数类型
5、variable names sql执行结果变量名
6、result variable names 所有结果当做一个对象存储
7、query timeouts 查询超时时间
8、 handle results 处理结果集
Jmeter 非 GUI 界面
安装JDK8
[root@ecs-8yZb5 ~]# mkdir -pv /usr/local/software
[root@MiWiFi-R3P-srv ~]# cd /usr/local/software/
[root@MiWiFi-R3P-srv software]# tar -zxvf jdk-8u181-linux-x64.tar.gz
[root@MiWiFi-R3P-srv software]# mv jdk1.8.0_181 jdk8
[root@MiWiFi-R3P-srv software]# vim /etc/profile
JAVA_HOME=/usr/local/software/jdk8
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
[root@MiWiFi-R3P-srv software]# source /etc/profile
[root@MiWiFi-R3P-srv software]# java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
Jmeter上传和jmx脚本
-h 帮助
-n 非GUI模式
-t 指定要运行的 JMeter 测试脚本文件
-l 记录结果的文件 每次运行之前,(要确保之前没有运行过,即xxx.jtl不存在,不然报错)
-r Jmter.properties文件中指定的所有远程服务器
-e 在脚本运行结束后生成html报告
-o 用于存放html报告的目录(目录要为空,不然报错)
# 不要输出报告
/usr/local/software/apache-jmeter-5.5/bin/jmeter -n -t /usr/local/software/apache-jmeter-5.5/executeproject/SuperPC.jmx
# 守护进程启动
nohup /usr/local/software/apache-jmeter-5.5/bin/jmeter -n -t /usr/local/software/apache-jmeter-5.5/executeproject/SuperPC.jmx &
# 计划任务
[root@MiWiFi-R3P-srv ~]# vim /usr/local/software/jmeter.sh
#!/bin/bash
nohup /usr/local/software/apache-jmeter-5.5/bin/jmeter -n -t /usr/local/software/apache-jmeter-5.5/executeproject/SuperPC.jmx &
[root@MiWiFi-R3P-srv ~]# chmod +x /usr/local/software/jmeter.sh
[root@MiWiFi-R3P-srv ~]# crontab -e
*/9 * * * * /usr/local/software/jmeter.sh
# 非GUI压测命令
[root@localhost apache-jmeter-4.0]# jmeter -n -t /software/apache-jmeter-4.0/jmx/linux_uses_api.jmx -l /software/apache-jmeter-4.0/jtl/result.jtl -e -o /software/apache-jmeter-4.0/result
Jmeter 压测接口的性能优化
- 使用非 GUI 模式:jmeter -n -t test.jmx -l result.jtl
- 少使用 Listener, 如果使用-l 参数,它们都可以被删除或禁用。
- 在加载测试期间不要使用“查看结果树”或“查看结果”表监听器,只能在脚本阶段使用它们来调试脚本。
- 包含控制器在这里没有帮助,因为它将文件中的所有测试元素添加到测试计划中。]
- 不要使用功能模式,使用 CSV 输出而不是 XML
- 只保存你需要的数据,尽可能少地使用断言
- 如果测试需要大量数据,可以提前准备好测试数据放到数据文件中,以 CSV Read 方式读取。
- 用内网压测,减少其他带宽影响压测结果
- 如果压测大流量,尽量用多几个节点以非 GUI 模式向服务器施压
Jmeter 压测生成多维度图形化 HTML 测试报告
# 打包结果目录
[root@localhost apache-jmeter-4.0]# zip -r test.zip /software/apache-jmeter-4.0/result
dashboard
Charts 报表
1)Over Time(随着时间的变化)
Response Times Over Time:响应时间变化趋势
Response Time Percentiles Over Time (successful responses):最大,最小,平均,用 户响应时间分布
Active Threads Over Time:并发用户数趋势
Bytes Throughput Over Time:每秒接收和请求字节数变化,蓝色表示发送,黄色表示接受
Latencies Over Time:平均响应延时趋势
Connect Time Over Time :连接耗时趋势
2)Throughput
Hits Per Second (excluding embedded resources):每秒点击次数
Codes Per Second (excluding embedded resources):每秒状态码数量
Transactions Per Second:即TPS,每秒事务数
Response Time Vs Request:响应时间和请求数对比
Latency Vs Request:延迟时间和请求数对比
3)Response Times
Response Time Percentiles:响应时间百分比
Response Time Overview:响应时间概述
Time Vs Threads:活跃线程数和响应时间
Response Time Distribution:响应时间分布图
分布式压测
- 普通压测:单台机可以对目标机器产生的压力比较小,受限因素包括 CPU,网络,IO 等
- 分布式压测:利用多台机器向目标机器产生压力,模拟几万用户并发访问
Jmeter 分布式压测原理
- 总控机器的节点 master,其他产生压力的机器叫“肉鸡” server
- master 会把压测脚本发送到 server 上面
- 执行的时候,server 上只需要把 jmeter-server 打开就可以了,不用启动 jmeter
- 结束后,server 会把压测数据回传给 master,然后 master 汇总输出报告 配置详情
JDK 安装
[root@localhost test]# tar -zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
[root@localhost jdk1.8.0_91]# pwd
/usr/local/jdk1.8.0_91
[root@localhost jdk1.8.0_91]# vim /etc/profile
JAVA_HOME=/usr/local/jdk1.8.0_91
export JAVA_HOME
CLASSPATH=.:$JAVA_HOME/lib
export CLASSPATH
PATH=$PATH:$JAVA_HOME/bin:$CLASSPATH
export PATH
[root@localhost jdk1.8.0_91]# source /etc/profile
[root@localhost jdk1.8.0_91]# java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
压测注意事项
- 关闭防火墙或开放响应端口
- 同一网段
- 相同版本的 JDK 和 Jmeter
- 为 RMI 设置 SLL 或者禁用
- 测试尽力使用内网地址,避免公网的带宽局限性
角色节点分布
Project 192.168.31.230
Master 192.168.31.251
Slave 192.168.31.250 192.168.31.240
Master 节点
Slave 节点
# 修改堆最小内存大小,避免机器配置过报错
[root@localhost apache-jmeter-4.0]# vim /software/apache-jmeter-4.0/bin/jmeter
: "${HEAP:="-Xms124m -Xmx126m -XX:MaxMetaspaceSize=256m"}"
# 修改属性文件
[root@localhost apache-jmeter-4.0]# vim /software/apache-jmeter-4.0/bin/jmeter.properties
server.rmi.ssl.disable=true
# 启动服务
[root@centos7_two software]# /software/apache-jmeter-4.0/bin/jmeter-server
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[192.168.31.240:42165](local),objID:[-66aa4768:16d438059bf:-7fff, -4045977157834656227]]]
Starting the test on host 192.168.31.240:8899 @ Wed Sep 18 16:34:10 CST 2019 (1568795650607)
Finished the test on host 192.168.31.240:8899 @ Wed Sep 18 16:34:50 CST 2019 (1568795690355)
Jmeter 分布式测试问题汇总
主机名
java.net.UnknownHostException
hostname 命令获取机器名称,追加一个映射 iZwz95j86y235aroi85ht0Z
vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
120.79.160.143 iZwz95j86y235aroi85ht0Z
RMI over SLL
jmeter.property里面 server.rmi.ssl.disable 改为 true,表示禁用
内存不足
There is insufficient memory for the Java Runtime Environment to continue.
[root@localhost apache-jmeter-4.0]# vim /software/apache-jmeter-4.0/bin/jmeter
: "${HEAP:="-Xms124m -Xmx126m -XX:MaxMetaspaceSize=256m"}"