JMeter 是一款由 Apache 开发的开源性能测试工具,可以模拟大量用户同时访问网站或接口,用于进行接口测试、压力测试和性能分析。它支持配置请求参数、提取响应数据、设置并发数和循环次数,并通过图形报告查看响应时间、错误率和吞吐量等指标,帮助开发和测试人员评估系统在高负载下的稳定性和性能。
基本流程
1.创建线程组
1.线程数:有多少个用户同时进行发送
2.Ramp-Up:表示多久把这些用户“全部启动起来”(单位:秒)
eg.设置线程数为 10,Ramp-Up 为 20 秒,则每 2 秒启动 1 个用户。3.循环次数:需要循环多少次
eg.线程数10 循环次数:5 每个线程发送5次共发生50请求
2.添加取样器
3.填写HTTP请求的相关数据
可以先用postman检测是否可以发送成功,并直观得到参数有哪些
端口号不用填 直接使用默认https默认端口号 443
4.在“线程组”下添加“查看结果树”监听器
5.点击“启动”按钮运⾏,查看接⼝测试结果
元件作⽤域和执⾏顺序
1.作用域指的是:一个元件对哪些内容“起作用”。
两个取样器各自发一个请求
2.执行顺序是指:JMeter 会从上往下,按顺序执行每一个节点。
重点组件
1.线程组
控制JMeter将⽤于执⾏测试的线程数,也可以把⼀个线程理解为⼀个测试⽤⼾。
线程数:⼀个线程即⼀个测试⽤⼾,设置发送的请求次数
Ramp-up时间(秒):设置性能测试运⾏时间,单位为秒
循环次数:
◦ 配置指定次数:控制脚本循环执⾏的次数
◦ 配置循环永远
▪ 需要调度器配置使⽤
▪ 运⾏时间:脚本执⾏时间
▪ 延迟启动时间:脚本等待指定时间才能运⾏
2.HTTP取样器
添加必需的配置:
http协议
http主机名/IP
端⼝
◦ http协议端⼝号80
◦ https端⼝号443
请求⽅法
路径(⽬录+参数)
内容编码(默认的ISO国际标准,但对中⽂⽀持不友好,可以使⽤utf-8)
参数
◦ 参数可以拼在路径⾥,也可以卸载参数中
◦ POST参数要放到消息体数据中{wd:test}
3.查看结果树
Thread Name:线程组名称
Sample time:发送请求时间
load time:响应时间
Response code :接⼝响应状态码
4.HTTP请求默认值
配置原件
统一配置公共的参数(如协议、IP、端口号),避免在每个接口请求中重复填写,提高效率。(相当于函数的缺省值 具体以后面取样器实际填写为准)
5.HTTP信息头管理器
给 HTTP 请求的请求头中添加字段信息,比如
Content-Type
、Authorization
、User-Agent
等,让请求更真实或符合接口要求。在实际的接口调用中,很多服务器会根据请求头判断请求是否合法、是否登录、是否为浏览器访问等。例如:
HTTP请求头管理器会把添加的参数字段 加入到所有管理的http请求的请求头中
请求头字段 作用说明 Content-Type
告诉服务器数据格式,如 application/json
Authorization
一般用来传登录后返回的 token User-Agent
模拟浏览器访问用 Cookie
模拟会话登录状态 ![]()
HTTP请求包含三个部分 请求行+请求头+请求体
HTTP请求默认值 中添加的字段,会添加在哪里?
1.get方式 会加在请求行中的请求URL中
2.post方式 会加在请求体中
5.JSON提取器
JSON 提取器就是从接口响应中的 JSON 数据里,提取某些字段值,并存到变量中,供后续请求使用。
作用场景:接口依赖,比如:
登录接口返回
token
,后面的请求需要带上它做身份验证;博客列表接口返回
blogId
,后续要“查看博客详情”就要用这个 ID。比如说我们先对博客登录界面进行测试,后面要对登录后的页面进行测试。这时候就需要登录请求返回的JSON中token字段进行身份认证。
1.找到目标字段路径
在 JMeter 中选中登录接口的 “查看结果树”监听器,执行登录请求后,切换到 “响应数据” 页签。找到返回的 JSON,可能长这样:
{ "code": 200, "message": "登录成功", "data": { "token": "abc123xyz456" } }
这时你就知道 token 的字段名是 token,完整路径是 $.data.token。
2.将目标值放在自定义的变量中
将目标字段的值存放在token变量中 (它的作用域仅限登录取样器中 只会获取登录的目标字段的值。如果放在全局 如果其它取样器中也有改字段就会覆盖 )
3.配合HTTP信息头管理器
给每个http请求的请求头中加上token:${token}字段 (${token}取出token变量的内容),这样所有http请求中都包含登录请求返回的JSON中toekn字段 进行身份认证。
JSON 操作符参考表
操作符 含义说明(通俗理解) $
表示根元素(最外层)
比如整个 JSON 的起点@
当前元素(通常用于过滤表达式中) *
通配符,表示“所有内容”
如:$[*]
表示所有数组元素..
递归查找所有符合条件的节点(不管在哪一层) .name
点语法,访问某个子字段
如:$.data.token
['name']
用中括号访问字段名,适合带特殊字符的字段 [0]
,[1]
按数组索引取值
如:$[0].title
取第一个元素的 title[0,2,4]
取多个下标值
如:取第1、3、5个数据[0:3]
数组切片,表示从第0个到第2个(不包含第3个) [?(@.id==3)]
过滤器表达式,表示筛选出 id=3
的元素eg.
{ "code": 200, "data": [ {"id": 1, "name": "张三"}, {"id": 2, "name": "李四"}, {"id": 3, "name": "王五"} ] }
想要提取的值 使用的 JSONPath 表达式 所有 id
值$..id
第一个用户的 name
$.data[0].name
筛选出 id=3 的 name
$.data[?(@.id==3)].name
6.JSON断⾔
接⼝发送请求成功,响应码为200并不能完全代表接⼝请求成功,我们更多需要关注接⼝响应数据是否符合预期。判断请求返回的JSON中是否存在目标字段以及值是否符合预期
eg.如果我们想断言 x-amzn-trace-id 这个字段的值怎么办?
1.先定位到这个字段的路径
1.选择JSON Path Tester进行查找 2.$代表进入根元素 .headers进入headers对象
["x-amzn-trace-id"]:字段名中有 -,必须用中括号加双引号访问
2.进行断言操作
指定断言字段路径 以及期望值
可以看到断言失败了,为什么?因为这个值是动态变化的.哪这么进行断言呢?
正则表达式
正则表达式是一种字符串模式匹配语法,可以用来模糊匹配字段内容,在 JSON断言中属于“高级匹配方式”。虽然我们不知道字符串具体的内容,但我们知道大致长度 是字符还是数字
记得勾选正则表达式操作
常用正则转义字符(预定义字符类)
符号 含义 匹配示例 \d
匹配任意一个数字(0–9) \d
→ 匹配0
到9
中任一位\D
匹配任意一个非数字字符 A
,b
,@
等都能匹配\s
匹配任意一个空白字符(空格、制表符、换行) 、 \t
、\n
等\S
匹配任意一个非空白字符 所有除了空格/换行/制表符的字符 \w
匹配字母、数字、下划线(等价于 [A-Za-z0-9_]
)abc123_
\W
匹配非字母、数字、下划线 比如 @
,-
,空格
.
匹配任意一个字符(除了换行) 如 a.c
→abc
,axc
常用正则表达式符号
表达式 说明 示例匹配 .
匹配任意一个字符 a.c
→ 匹配abc
,axc
*
匹配前一个字符 0 次或多次 a*
→ 匹配 ``,a
,aa
+
匹配前一个字符 1 次或多次 a+
→ 匹配a
,aa
?
匹配前一个字符 0 或 1 次 a?
→ 匹配 ``,a
^
匹配字符串的开头 ^abc
→ 匹配以abc
开头的字符串$
匹配字符串的结尾 abc$
→ 匹配以abc
结尾的字符串[]
匹配方括号中的任意一个字符 [aeiou]
→ 匹配任何元音字母[^]
匹配不在括号中的字符 [^0-9]
→ 匹配非数字字符{n}
恰好匹配 n 次 a{3}
→ 匹配aaa
{n,}
至少匹配 n 次 a{2,}
→ 匹配aa
,aaa
...{n,m}
匹配 n 到 m 次 a{2,4}
→ 匹配aa
,aaa
,aaaa
` ` 或操作 ()
分组匹配 (ab)+
→ 匹配ab
,abab
...
7.同步定时器
同步定时器就像一个集合点,让多个线程(虚拟用户)一起“等一等”,等人到齐后一起发起请求,制造真正的“并发冲击”
等准备好的线程数 >=5时进行同时发送
注意:如果发送的线程数 不是并发的倍数,会因为达不到规定的线程数导致发送不出去。建议使用循环发送 规定循环时间 。(并不是说一定会一次性发送5个,如果准备好的线程数》5也可以同时进行发送 因此就算是倍数关系,也建议用循环发送)
8.事务控制器
把多个请求合并成一个“事务”进行性能测试,统计这一整组操作所耗费的总时间。
为什么要用事务控制器?
在真实系统中,一个用户操作通常不只发起一个请求,比如:
提交订单操作可能包括:
登录
查询购物车
生成订单
支付
如果你单独测每一步,就无法准确知道“整个下单过程用了多长时间”。
使用事务控制器,可以把这些步骤包在一起,统计整个流程的总响应时间。
9.CSV数据⽂件设置
在性能测试中,我们经常需要模拟多个用户登录。但如果用户名/密码都写死,那每个线程用的都是同一个账号,太假了。
用 CSV 数据文件就能让每个线程使用不同的参数,比如不同的用户名和密码。
1.新建csv文件保存账号密码
userinfo.csv
2.找到新建的csv文件 并设置变量名
username password
配置项 | 意义 | 示例 |
---|---|---|
文件名 | 指定 CSV 文件的路径(建议绝对路径) | D:/jmeter/users.csv |
文件编码 | 文件使用的编码 | UTF-8 |
变量名称 | 每列数据对应的变量名,用逗号隔开 | username,password |
是否忽略首行 | 如果 CSV 第一行是表头,就选
|
True (跳过第一行) |
分隔符 | 列与列之间的分隔符,默认逗号 | , |
遇到文件结束是否循环 | 数据用完是否重新从头开始 | False (用完即停) |
线程结束配置 | 当上面为 False 时,勾选“Stop thread on EOF”可以让线程退出 | 推荐勾选 |
3.在HTTP取样器中配置参数
从表中循环读取 第一个线程读第一个 第二个线程读第二个 ...
(我启动的多线程 所以第一个结果未必真的是第一个线程执行的)
10.HTTP Cookie管理器
Cookie 和 Token 有什么区别?
对比项 Cookie Token 作用 ✔️ 保存登录状态,验证身份 ✔️ 保存登录状态,验证身份 存在哪里 浏览器自动保存 前端程序自己保存(LocalStorage 等) 怎么发出 浏览器自动带上(请求头里) 需要手动加到请求头 Authorization 是否依赖服务器记住你 ✔️ 是(服务端 session) ❌ 否(token 自带身份信息) 适合场景 传统网页系统,服务端渲染 移动端、前后端分离项目、接口 API
总结一句话:
Cookie 和 Token 都是“登录后的身份通行证”,作用一样,但用法不同。
就像你出门可以刷身份证(Cookie)也可以扫码出示健康码(Token),都是证明“你是谁”。
如果你在测试系统是“老式网页”,大概率用的是 Cookie;
它们的 工作方式不一样,所以使用场景、优缺点也不一样:
如果是 移动端 App、Vue/React 的前后端分离系统,就可能是 Token。
不需要手动添加Cookie 登录成功后自动给后面请求添加
各项功能说明:
1. “每次反复清除Cookies?”(Clear cookies each iteration)
不勾选(默认):登录一次后,cookie 会一直保存,后续请求都能用同一个 cookie(适合登录保持测试)
勾选后:每次循环都清除 cookie,相当于“每次都新开一个浏览器窗口”
📌 建议:
登录后需要保持会话 → 不勾选
测试重复登录、模拟不同用户 → 勾选
2. Use Thread Group configuration to control cookie clearing
让线程组来控制 cookie 清理逻辑(高级选项)
一般默认不勾选即可
3. 存储方式下拉框(standard / compatibility)
standard
(标准模式)✅ 推荐用
compatibility
(兼容模式):如果你的服务器对 cookie 解析不严格,可以用这个解决异常行为
4. 下方手动添加 Cookie(可选)
名称 值 域 路径 安全 name cookie名 绑定哪个域名(可为空) 路径限制 是否仅 HTTPS 可用 🔧 用途:如果你需要提前设置某个 cookie(比如绕过登录、测试 token),可以手动填。
最常用的用法(标准做法):
在“线程组”下添加一个 HTTP Cookie 管理器
不勾选“每次清除”
保持 standard 模式
登录接口执行成功后,后续所有请求会自动带 cookie,不需要你手动加!
项目 Cookie(配好 Cookie 管理器) Token(如 JWT) 接口响应中返回 Set-Cookie: sessionid=abc123
{"token": "xxxx"}
你要做什么 ✅ 不用做任何事,自动保存自动发出 ❗ 需要提取(JSON提取器)+ 手动加请求头 JMeter 是否自动带上 ✅ 会自动加上: Cookie: sessionid=abc123
❌ 不会,需要你写到 Authorization
头里
Jmeter插件
1.Stepping Thread Group梯度压测线程组
它是一个增强型线程组插件,可以一步一步按节奏增加线程(用户),用于模拟真实的“用户逐步上线”场景,非常适合做压测、突发流量、稳定性测试。
项目 | 设置值 | 含义解释 |
---|---|---|
This group will start | 20 | 总共将启动 20 个线程(用户) |
First, wait for | 0 | 启动前 不等待,立即开始 |
Then start | 0 | 一开始 不启动线程(第 0 秒不发用户) |
Next, add | 5 | 每次增加 5 个线程 |
threads every | 10 | 每隔 10 秒 增加一批线程 |
using ramp-up | 1 | 每批线程在 1 秒内 启动完成 |
Then hold load for | 60 | 所有线程启动完后 保持 60 秒不变,进行稳定压测 |
Finally, stop | 5 every 1 sec | 最后阶段,每 1 秒 停止 5 个线程,直到全部退出 |
监控器
Response Times Over Time
作用:
用于监控整个测试过程中事务响应时间的变化趋势。
图表含义:
横坐标(X轴): 运行时间
纵坐标(Y轴): 响应时间(单位:毫秒)
使用价值:
实时观察平均响应时间的变化
判断系统在某些时间点是否存在响应波动或延迟上升
帮助定位潜在的性能瓶颈
举例说明:
如果图表中某一时间点响应时间突然上升,可能代表系统在该时刻遇到了资源占用、GC阻塞或后端服务延迟等问题。
Transactions per Second(TPS)
作用:
用于监控系统在每秒钟内处理的事务数量,即吞吐量。
图表含义:
每一个点代表当前秒内系统成功处理的请求数(TPS)
使用价值:
反映系统在单位时间内的处理能力
TPS 越高,说明系统承压越强
可用于分析系统负载极限与性能瓶颈
典型现象:
TPS 随并发上升而上升 → 系统性能良好
TPS 到达一定高度后下降或波动 → 达到瓶颈,需关注资源消耗
测试报告
生成测试报告指令:
jmeter -n -t your_test.jmx -l result.jtl -e -o ./report/
result.jtl
日志文件可以不存在,但如果存在必须是空的
./report/
目录可以不存在,JMeter 会自动创建;但如果存在,也必须为空
参数 含义 -n
非GUI模式运行 -t
指定要执行的 .jmx
脚本 (如果名字中间带空格 要用 " " 引用)-l
运行日志输出到 .jtl
文件-e
表示生成 HTML 报告 -o
指定报告输出目录(必须是空目录或不存在) Jmeter -n -t 脚本⽂件 -l ⽇志⽂件 -e -o ⽬录
jmeter -n -t "jp@gc - Stepping Thread Group.jmx" -l result.jtl -e -o ./report/
性能分析
响应时间(Response Time)
定义:
指客户端发送请求 → 接收到完整响应所花费的时间。
意义:
响应时间越短,用户体验越好;一旦超过 SLA(服务等级协议)设定的阈值,说明系统性能已出现瓶颈。
注意事项:
要关注在多少并发线程数下开始出现响应变慢或抖动。
判断是持续性变慢,还是偶发性卡顿。
常见异常表现:
表现 | 可能原因 |
---|---|
响应时快时慢(抖动) | 系统负载不稳定、GC 频繁、网络波动 |
并发增加后持续变慢 | 系统达到瓶颈(线程池/数据库/IO/服务端) |
错误率(Error Rate / Reliability)
定义:
请求失败数量占总请求数量的比例,用于衡量系统的可靠性。
目标标准:
通常要求错误率 < 0.01%(即 99.99% 可用性),在高并发场景下尤其关键。
常见错误来源:
错误原因 | 示例说明 |
---|---|
接口参数错误、URL拼错 | HTTP 4xx 错 |
代码 Bug、内存溢出、线程死锁 | HTTP 5xx 错 |
后端限流、熔断、降级机制触发 | 如 Nginx 报错 429、业务接口限流等 |
概念补充:
熔断(Circuit Breaker):
当某接口失败率突增或响应超时严重时,系统自动断开对该服务的调用,防止连锁故障。
示例:某支付渠道不稳定,收银台临时关闭“微信支付”功能。
降级(Degrade):
当系统压力较大时,主动关闭部分非核心功能,保留核心功能的可用性。
示例:腾讯视频发生异常时,昵称显示“腾讯用户”,为降级处理。
吞吐量(Throughput)
定义:
单位时间内系统能处理的请求数量,通常以 TPS(Transactions Per Second)表示。
意义:
吞吐量越大,说明系统处理能力越强,资源利用率越高。
常见变化规律:
吞吐变化 | 含义说明 |
---|---|
吞吐量稳定增长 | 系统性能良好,尚未达到资源瓶颈 |
吞吐量波动很大 | 性能不稳定,可能存在垃圾回收、锁竞争等问题 |
吞吐量持续下降 | 系统已达瓶颈或处于崩溃边缘,如线程数不够、CPU耗尽 |
性能测试核心分析方法总结表
指标名称 | 关注重点 | 异常表现 | 可能原因 | 优化建议 |
---|---|---|---|---|
🔹响应时间 | 单请求耗时、平均响应趋势 | - 响应时间长- 抖动大- 超过SLA | - 系统资源瓶颈(CPU/IO/GC)- 并发过高- 网络波动 | - 优化SQL/代码- 加缓存- 增加线程池大小 |
🔹错误率 | 成功率、失败请求比例 | - 接口失败- 4xx/5xx 错误 | - 参数错误/接口Bug- 系统资源耗尽- 限流熔断降级触发 | - 检查日志/接口逻辑- 增强服务容错 |
🔹吞吐量 | TPS(每秒事务数)、稳定性 | - 吞吐波动大- TPS下降- 并发升吞吐不升 | - 已达系统上限- CPU打满/线程阻塞- 响应变慢反影响并发 | - 增强并发处理能力- 多实例部署- 提前扩容 |