JMeter
一个开源的负载测试工具,可以用于测试静态和动态资源,确定服务器的性能和稳定性
下载
地址:https://jmeter.apache.org/download_jmeter.cgi
安装
需要安装 JDK8
1 | $ java -version |
将下载的 JMeter 压缩包解压到指定目录后,执行 bin 目录下的 jmeter.sh
即可启动
windows 双击
jmeter.bat
配置环境变量
在.bashrc 中添加
1
export PATH=$HOME/opt/apache-jmeter/bin:$PATH
应用
1
source .bashrc
使用
切换中文
Options -> Choose Language -> Chinese (Simplified)
安装插件
下载Plugins Manager插件,放到 jmeter目录的
/lib/ext
下面,重启重启后在
选项
菜单中有一个 Plugins Manager 选项在 Avaliable Plugins 选项下搜索并安装
3 Basic Graphs
显示 TPS 的实时折线图
5 Additional Graphs
显示吞吐量,连接时间等
PerfMon(Servers Performance Monitoring)
监控CPU、内存、磁盘IO、网络IO
需配合 PerfMon Server Agent 使用,但是很久没更新
各种组件
JMeter 的组件有线程组、取样器、配置元件、前置处理器、后置处理器、定时器、断言、逻辑控制器、监听器。
- 取样器:生成各种协议的请求,主要用于编辑用户请求时的传参数据。
- 配置元件:辅助请求,简化请求数据编辑的内容。
- 线程组:管理请求的运行时间和数量的限制。进行性能测试时必须设置。
- 前置处理器:请求之前的数据管理。
- 后置处理器:响应之后的数据管理。
- 断言:针对请求后的响应内容做预期结果的判断。
- 逻辑控制器:控制各种请求或元件的运行顺序和规则。
- 监听器:对最后结果进行展示,可以图形展示,也可以数据形式进行展示。
- 定时器:控制请求的运行时间。
JMeter 的组件其作用域
,例如在线程组下添加的配置元件会针对整个线程组中所有的请求,在某个请求下添加的配置元件仅针对该请求
定义变量
用户定义的变量
- 添加测试服务器的 host 和 port 等信息
CSV 数据文件设置
从CSV文件中读取参数,构造动态变化的业务请求
CSV格式
1 | id,name |
配置
- 如果添加了表头,则需要将
忽略首行
设置为true
函数变量
内置变量
vars
线程组 局部变量,只能在同一线程组内传递数据
通常用于在测试执行期间动态生成值,例如从响应中提取数据并将其存储在变量中供后续请求使用。
通过如下方式设置和访问:
- 在非 beanshell 环境里使用
${varName}
语法访问变量的值。 - 在 beanshell 环境里使用
vars.get("varName")
语法访问变量的值,vars.put("varName", "value")
语法设置变量的值。
props
JMeter 全局变量,可以跨线程组传递数据
通常用于在测试执行期间传递数据
通过如下方式设置和访问:
- 在非 beanshell 环境里使用
${__P(propName)}
语法访问变量的值。 - 在 beanshell 环境里使用
props.get("propName")
语法访问变量的值,props.put("propName", "value")
语法设置变量的值。
引用变量
通过${variable}
引用
如果是字符串格式,则用双引号包裹,不影响解析
函数
通过函数动态生成一些请求参数
time
动态生成13位时间戳
digest
动态生成摘要
uuid
返回一个 uuid v4 版本的随机id
引用方式:
1 | ${__UUID()} |
JSON Path
由一系列的属性名和数组索引组成:以 “$.” 开头,用“.”和“[]”分隔
1 | { |
- $.name:获取 “John”
- $.cars[0].name:获取 “Ford”
- $.cars[1].models[2]:获取 “X5”
Bean Shell
一种完全符合 Java 语法规范的脚本语言。允许用户在 JMeter 中编写自定义脚本
JMeter 中很多地方都可以使用 BeanShell 脚本,如:采样器(BeanShell Sampler),前置处理器(BeanShell PreProcessor),后置处理器(BeanShell PostProcessor),断言(BeanShell Assertion),定时器(BeanShell Timer),监听器(BeanShell Listener)。使用 BeanShell 脚本可以很容易地扩展 JMeter 的功能
- 在测试计划中使用复杂的逻辑控制。
- 动态地生成HTTP请求参数。
- 在测试过程中处理响应数据。
- 自定义结果分析器。
常用内置对象
log
记录日志。Jmeter 用 log4j 记录日志,打印的日志会记录到bin/jmeter.log文件。输出信息和错误的API 分别是 log.info``()
和 log.error()
。
多个字符串需要用
+
拼接
1 log.info("a"+vars.get("token"))
vars
操作 JMeter 变量。可以在 HTTP 请求等地方用到
Jmeter 变量是在线程启动时,拷贝到线程的,类似线程的局部变量。所以一个线程更新了变量,不会影响到另一个线程。
获取变量:
1 | vars.get("name") |
设置变量。如果变量不存在会创建:
1 | vars.put("key", "value") |
props
操作 JMeter 的配置文件:jmeter.properties。
获取配置的值:
1 | props.get("key") |
设置配置的值:
1 | props.put("key", value) |
data
当前请求的响应数据,可以用String str = new String(data, “utf-8”)转成字符串再打印出来。类型是byte[],即字节数组。
示例
生成随机数,并设置到 JMeter 变量上
1 | import java.util.Random; |
计算两个变量的和
1 | int num1 = Integer.parseInt(vars.get("num1")); |
构造 HTTP 请求参数
1 | String param1 = URLEncoder.encode(vars.get("param1"), "UTF-8"); |
获取 HTTP 响应头中的某个值
1 | import org.apache.http.Header; |
执行 HTTP 请求并解析响应数据
1 | import org.apache.commons.io.IOUtils; |
发送电子邮件
1 | import javax.mail.*; |
概念
RT
response time 响应时间
请求从开始到收到响应花费的时间
Transaction
一个完整的请求-响应流程,即一个客户机向服务器发送请求然后服务器做出响应的过程
VU
virtual user 虚拟用户数(并发用户),即JMeter 中的一个线程
- 注册用户一般指数据库中存在的用户
- 在线用户只是”挂”在系统上,对服务器不产生压力
- 并发用户会对服务器产生压力
TPS
Transactions per Seconds
单位时间内完成的事务个数,是衡量系统性能的一个非常重要的指标
请求总数/总时长
线程总数/启动时间
线程总数由CPU型号决定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 $ lscpu
架构: x86_64
CPU 运行模式: 32-bit, 64-bit
字节序: Little Endian
Address sizes: 39 bits physical, 48 bits virtual
CPU: 12 # 该处理器可以并行处理的线程总数为 12
在线 CPU 列表: 0-11 # 系统识别到的 CPU 核心编号
每个核的线程数: 2 # 每个核心支持 2 个线程
每个座的核数: 6 # 这是一个六核心处理器
座: 1 # 这台机器上安装了一个 CPU
NUMA 节点: 1
厂商 ID: GenuineIntel
CPU 系列: 6
型号: 151
型号名称: 12th Gen Intel(R) Core(TM) i5-12400
性能评价
- 系统的性能由TPS决定,跟并发用户数没有多大关系
- 一般情况下,大型系统(业务量大、机器多)做压力测试,10000~50000个用户并发,中小型系统做压力测试,5000个用户并发比较常见
测试指标
一般分为业务指标、资源指标、应用指标、前端指标。
- 业务指标:如并发用户数、TPS(系统每秒处理事务数)、成功率、RT。
- 资源指标:如CPU资源利用率、内存利用率、I/O、内核参数(信号量、打开文件数)等。
- 应用指标:如空闲线程数、数据库连接数、GC/FULL GC次数、函数耗时等。
- 前端指标:如页面加载时间、网络时间(DNS、连接时间、传输时间等)