JMeter使用及其性能压测
目录
4.2.3 调度器配置(Scheduler Configuration)
1. HTTP请求默认值(HTTP Request Defaults)
2. CSV数据文件设置(CSV Data Set Config)
3. HTTP信息头管理器(HTTP Header Manager)
4. 用户定义的变量(User Defined Variables)
5. Cookie管理器(HTTP Cookie Manager)
6. JDBC连接配置(JDBC Connection Configuration)
9. 登录配置元件(Login Config Element)
(3)集成到CI/CD(通过Jenkins + Maven执行)
一、JMeter基本信息
1.JMeter概述
- 定义与定位:Apache开源性能测试工具,支持多协议(HTTP/HTTPS、FTP、JDBC等)。
- 核心功能:性能测试、压力测试、接口测试、负载测试。
- 适用场景:Web应用、API、数据库、微服务等。
2.核心特点
- 跨平台(Java开发)。
- 图形化界面 + 命令行模式(适合CI/CD)。
- 插件扩展机制(如自定义脚本、第三方插件)。
3.安装与配置
- 系统要求(JDK环境、内存配置)。
由于jmeter是java开发的,需要安装java的jdk环境
- 安装步骤(Windows/Linux/Mac)。
在官网下载jmeter安装包安装在制定地方即可
下载网址:Apache JMeter - Download Apache JMeter
- 目录结构说明(bin, lib, plugins等)。
4.核心组件
4.1 测试计划(Test Plan)
4.1.1 定义
【测试计划】(相当于多个进程或者单个进程),模拟本次运行过程中所有业务的接口请求
4.1.2 结构
包含:多个线程组或者单个线程组
单个线程组:单个线程组中的请求是顺序执行的
多个线程组:每个线程组设置线程数,表示操作数,一个线程数相当于一个用户
注:线程组中的每个请求表示操作,相当于一个线程
测试计划中每个线程组默认并发执行的,即当存在多个线程组,每个线程组中又存在多个请求,则执行顺序是并发执行的
【设置顺序执行】:【测试计划】页面勾选【独立运行每个线程组】,则会按照执行完一个线程组中所有请求后,再执行下一个线程组的请求

4.2 线程组(Thread Group)
4.2.1 概念
- 可以理解为一个进程,比如如启动一个游戏;
- 正在运行的程序,线程:进程中的每一步操作,如游戏中的每一个玩家都是一个线程
- 线程的执行方式:
顺序执行:指多个线程按照顺序依次执行,如电影需要先下载再播放,对应先新增再删除
并发执行:多个线程同时执行,如多部电影同时下载,对应同时新增多个项目;并发执行需要在线程组中设置多个线程数
- 线程组作用:对线程进行分类,归组,方便管理线程
- 线程组设置界面详解:
4.2.2 基础参数
1. 线程数(Number of Threads, Users)
- 含义:模拟的并发用户数(即虚拟用户数)。
- 示例:设置为100,表示同时有100个用户执行测试脚本。
- 注意:实际并发量受硬件资源(CPU、内存)限制。
2. Ramp-Up时间(Ramp-Up Period, in seconds)
- 含义:所有线程启动完成所需的时间(单位:秒)。
- 示例:线程数=100,Ramp-Up=10 → 每秒启动10个线程。
- 用途:控制压力递增速度,避免瞬间高负载压垮系统。
3. 循环次数(Loop Count)
- 含义:每个线程执行测试脚本的循环次数。
- 示例:循环次数=5 → 每个线程执行5次完整脚本。
- 特殊值:勾选“无限循环”时,线程会持续运行直到手动停止。
4.2.3 调度器配置(Scheduler Configuration)
勾选“调度器”后,可设置时间范围控制测试执行时长:
1. 持续时间(Duration, seconds)
- 含义:测试计划运行的总时间(单位:秒)。
- 优先级:高于循环次数(即使循环未完成,超时后测试停止)。
2. 启动延迟(Startup Delay, seconds)
- 含义:线程组启动前的等待时间(用于同步或预热)。
- 示例:设置为60 → JMeter等待60秒后开始启动线程。
4.2.4 其他参数
1. Same User on Each Iteration
- 含义:是否每次循环使用同一用户(影响Cookie、Session复用)。
- 默认勾选:用户会话保持(如登录态)。
- 取消勾选:每次循环视为新用户(需重新登录)。
2. 延迟创建线程直到需要
- 含义:按需逐步创建线程(优化资源占用)。
- 适用场景:大规模并发测试时减少内存消耗。
4.2.5 参数配置示例
场景1:阶梯加压测试(压力测试)
- 线程数:100
- Ramp-Up时间:300秒(逐步加压到100用户,模拟真实用户增长)
- 循环次数:勾选“无限循环”
- 调度器:
- 持续时间:600秒(总测试时长为10分钟)
场景2:单用户功能测试(接口调试)
- 线程数:1
- Ramp-Up时间:1秒
- 循环次数:1
4.2.6 特殊线程组
setUp线程组:最先执行的线程组,一般用于初始化操作
tearDown线程组:最后执行的线程组,一般用于资源数据销毁,数据还原

4.2.7 注意事项
1. 资源消耗:
- 单机线程数不宜过高(建议不超过500),否则可能因内存不足导致OOM错误。
- 分布式压测时,通过多台机器分担线程数。
2. Ramp-Up时间与TPS关系:
- Ramp-Up时间越短,瞬间并发压力越大(适用于峰值测试)。
- Ramp-Up时间越长,压力递增越平滑(适用于容量规划)。
3. 循环次数 vs 持续时间:
- 需要固定时长测试(如稳定性测试)→ 使用调度器的“持续时间”。
- 需要固定次数测试(如验证接口幂等性)→ 使用“循环次数”。
4.3 取样器(Sampler)
4.3.1 定义
是用于向服务器发送请求并接收响应的核心组件。它模拟用户对目标系统的操作(如HTTP请求、JDBC查询、FTP上传等),是性能测试中定义具体操作的关键部分。
4.3.2 采样器的作用
1. 发送请求:如HTTP请求、数据库查询、FTP文件传输等。
2. 记录响应数据:JMeter会记录服务器返回的响应时间、状态码、内容等信息。
3. 支持性能分析:通过采样器收集的数据,可以分析系统的吞吐量、延迟、错误率等性能指标。
4.3.3 常见采样器类型
1. HTTP Request:发送HTTP/HTTPS请求(GET、POST等)。
2. JDBC Request:执行数据库SQL查询。
3. FTP Request:上传或下载文件到FTP服务器。
4. SOAP/XML-RPC Request:发送SOAP或XML-RPC请求。
5. JMS Publisher/Subscriber:测试消息队列(如ActiveMQ)。
6. TCP Sampler:通过TCP协议发送原始数据包。
4.3.4 如何使用采样器
步骤1:添加采样器
右键点击线程组 → Add → Sampler → 选择需要的采样器(如`HTTP Request`)。

步骤2:配置采样器参数
以HTTP Request为例:
- Protocol:HTTP或HTTPS。
- Server Name/IP:目标服务器地址(如`www.example.com`)。
- Port:服务器端口(如HTTP默认80,HTTPS默认443)。
- Path:请求路径(如`/api/login`)。
- Method:GET、POST、PUT等。
- Parameters/Body Data:请求参数或JSON/XML内容。

步骤3:添加监听器查看结果
采样器需要配合监听器(Listener) 才能查看测试结果:
- 右键点击采样器 → Add → Listener → 选择监听器(如`View Results Tree`、`Summary Report`)。

示例:发送HTTP POST请求
1. 添加HTTP Request采样器:
- Server Name: `api.example.com`
- Path: `/login`
- Method: `POST`
- Body Data: `{"username": "test", "password": "123456"}`
2. 添加请求头(如JSON格式):
- 右键点击HTTP Request → Add → Config Element → HTTP Header Manager。
- 添加`Content-Type: application/json`。
3. 添加断言(Assertion)(可选):
- 右键点击HTTP Request → Add → Assertion → `JSON Assertion`,验证响应内容。
4. 运行测试并查看结果:
- 使用`View Results Tree`监听器查看请求和响应详情。
4.3.5 最佳实践
1. 命名清晰:为每个采样器设置唯一且有意义的名称(如`Login_API_POST`),便于后续分析。
2. 参数化:使用`User Defined Variables`【用户自定义变量】或`CSV Data Set Config`【csv数据设置】动态替换请求参数。
3. 错误处理:添加`Response Assertion`【响应断言】验证响应是否成功。
4. 合理组织结构:将多个相关采样器放在一个事务控制器(Transaction Controller) 中,统计整体事务时间。
5. 避免冗余:使用`HTTP Cookie Manager`或`HTTP Cache Manager`模拟浏览器行为。
4.3.6 常见问题
1. 为什么采样器没有响应?
- 检查网络连接、服务器状态、端口和路径是否正确。
- 确认是否添加了`HTTP Header Manager`(如Content-Type)。
2. 如何发送文件上传请求?
- 在HTTP Request中勾选`Use multipart/form-data`,并添加文件路径参数。
3. 如何实现参数化?
- 使用`${变量名}`引用变量(如`${username}`),变量可通过CSV文件或用户自定义变量定义。
4.4 逻辑控制器(Logic Controller)
4.4.1 定义
在JMeter中,逻辑控制器(Logic Controller) 用于控制测试计划中采样器(Sampler)的执行顺序和逻辑流程。它们可以实现条件判断、循环执行、并行处理等复杂逻辑,帮助模拟更贴近真实场景的用户行为。
4.4.2 逻辑控制器的作用
1. 控制执行顺序:决定采样器的执行顺序(如顺序、随机、循环)。
2. 实现条件逻辑:根据条件决定是否执行某些请求(如`if`判断)。
3. 重复操作:循环执行一组请求(如登录后多次查询)。
4. 模块化测试计划:复用代码片段(如通过`Include Controller`或`Module Controller`)。
5. 并发与分组:模拟用户分组或并行操作(如`Parallel Controller`)。
4.4.3 常用逻辑控制器及用法
1. 简单控制器(Simple Controller)
- 作用:仅用于分组,无逻辑控制功能。用于组织测试计划结构。和线程组差不多,可将线程组下请求再度分类
- 用法:
- 右键点击线程组 → Add → Logic Controller → Simple Controller。
- 将需要分组的采样器拖入该控制器下。
---
2. 循环控制器(Loop Controller)
- 作用:循环执行其子节点(采样器或其他控制器)指定的次数。
- 用法:
- 添加控制器:右键点击父节点 → Add → Logic Controller → Loop Controller。

- 设置循环次数:


- Loop Count:固定次数(如5次)。
- Infinite:勾选后无限循环(需手动停止)。
- 将需要循环的采样器作为子节点添加到该控制器下。

---
3. 交替控制器(Interleave Controller)
- 作用:每次循环时,只执行其子节点中的一个(按顺序轮流执行)。
- 示例:模拟用户随机点击不同页面。
- 用法:
- 添加交替控制器,并在其下添加多个采样器(如`Page1`、`Page2`、`Page3`)。
- 每次线程组循环时,按顺序执行其中一个采样器。
---
4. 随机控制器(Random Controller)
- 作用:每次循环随机选择一个子节点执行。
- 示例:随机访问不同API接口。
- 用法:
- 添加随机控制器,并在其下添加多个采样器。
- 设置是否允许重复执行同一子节点(勾选`Ignore sub-controller blocks`)。
示意:每运行一次随机选择一个请求进行发送,即每次运行只发起随机控制器下的其中一个请求

---
5. 事务控制器(Transaction Controller)
- 作用:将多个采样器合并为一个事务,统计整体响应时间。
- 示例:统计登录到查询的完整流程时间。
- 用法:
- 添加事务控制器 → 勾选`Generate parent sample`(合并结果显示)。
- 将相关采样器作为子节点添加到事务控制器下。


---
6. If 控制器(If Controller)
- 作用:根据条件判断是否执行子节点。
- 用法:
- 添加If控制器 → 在`Condition`中输入判断条件(如`${JMeterThread.last_sample_ok}`表示上一个请求成功)。
- 支持JavaScript表达式或变量判断(如`${VAR} == 200`)。
- 注意:勾选`Interpret Condition as Variable Expression?`(若使用变量判断)。
---
7. While 控制器(While Controller)
- 作用:当条件满足时,循环执行子节点。
- 示例:循环执行直到响应中包含特定内容。
- 用法:
- 设置`Condition`(如`${__javaScript("${response}".indexOf("success") >= 0)}`)。
- 支持`LAST`关键字(当子节点执行失败时停止循环)。
---
8. 并行控制器(Parallel Controller)
- 作用:并行执行所有子节点(JMeter默认是顺序执行)。
- 示例:模拟用户同时上传文件和发送请求。
- 用法:
- 添加并行控制器 → 将需要并行的采样器放入其下。
- 注意:实际并发数受线程组的线程数限制。
---
9. Switch 控制器(Switch Controller)
- 作用:根据索引或变量值选择执行某个子节点。
- 示例:根据用户类型执行不同操作。
- 用法:
- 在`Switch Value`中填写子节点索引(从0开始)或变量名(如`${userType}`)。
- 子节点按顺序排列,匹配值后执行对应节点。
---
10. ForEach 控制器(ForEach Controller)
- 作用:遍历变量(如从CSV文件读取的数据),逐个执行子节点。
- 示例:遍历用户ID列表执行查询。
- 用法:
1. 使用`CSV Data Set Config`读取变量(如`user_1, user_2`)。
2. 添加ForEach控制器 → 设置`Input variable prefix`(如`user`)和`Output variable name`(如`currentUser`)。
3. 子节点中使用`${currentUser}`引用当前遍历的值。
---
11. 模块控制器(Module Controller)
- 作用:引用其他测试片段(Test Fragment)中的逻辑控制器。
- 示例:复用登录模块。
- 用法:
1. 在`Test Fragment`中定义可复用的控制器(如登录流程)。
2. 添加模块控制器 → 选择目标测试片段中的控制器。
---
12. 包含控制器(Include Controller)
- 作用:从外部JMX文件导入测试计划片段。
- 用法:
- 添加Include控制器 → 指定外部JMX文件路径。
- 注意:外部文件需为JMeter测试计划片段。
---
最佳实践
1. 组合使用:例如,在循环控制器内嵌套If控制器,实现复杂逻辑。
2. 参数化条件:使用变量(如`${LOOP_COUNT}`)动态控制循环次数。
3. 调试工具:配合`Debug Sampler`和`View Results Tree`验证逻辑是否正确。
4. 避免过度嵌套:嵌套过深可能导致测试计划难以维护。
---
常见问题
1. 为什么If控制器不生效?
- 检查条件表达式语法(如变量名是否正确)。
- 确认是否勾选了`Interpret Condition as Variable Expression`。
2. 如何停止While循环?
- 在子节点中设置变量(如`${__setVar(stop,true)}`),条件设为`${stop}`。
3. 事务控制器的时间包含子节点外的请求吗?
- 不包含,仅统计其直接子节点的总时间。
---
总结
逻辑控制器是JMeter实现复杂测试逻辑的核心工具,通过组合不同的控制器(如循环、条件、并行),可以模拟真实用户行为并优化测试效率。建议结合具体场景选择合适的控制器,并通过监听器(如`Aggregate Report`)分析执行结果。
4.5 监听器(Listener)
4.5.1 定义
JMeter监听器是用于收集和展示测试结果的关键组件,帮助用户分析性能数据。通过合理选择监听器并优化配置,可以高效获取性能测试数据,快速定位瓶颈,为系统优化提供依据。
4.5.2 常用监听器类型及用法
1.查看结果树(View Results Tree)
- 功能:显示每个请求的详细数据(请求头、响应数据、响应时间等)。
- 使用场景:调试脚本时验证请求/响应是否正确。
- 注意:正式测试时禁用,避免内存消耗过大。

2.聚合报告(Aggregate Report)
- 功能:汇总关键指标(平均响应时间、吞吐量、错误率、请求数等)。
- 使用场景:生成整体性能报告,支持导出为CSV文件。

3.图形结果(Graph Results)
- 功能:以图表展示响应时间、吞吐量趋势。
- 注意:高并发时可能影响性能,建议小规模测试使用。
4.汇总报告(Summary Report)
- 功能:类似聚合报告,但实时更新数据,适合监控运行中的测试。
5.响应时间图(Response Time Graph)
- 功能:专用于展示响应时间分布(百分比曲线)。
6.断言结果(Assertion Results)
- 功能:显示断言失败的具体信息,用于结果验证。
7.后端监听器(Backend Listener)
- 功能:将结果实时发送至外部系统(如InfluxDB + Grafana)。
- 使用场景:实时监控与可视化。
4.6 断言(Assertion)
4.6.1 断言的作用
断言用于验证服务器返回的响应数据、状态码、响应时间等是否符合预期,是接口测试和性能测试中结果校验的核心组件。
通过合理使用断言,可以确保测试结果的准确性,快速定位接口逻辑或性能问题。根据响应类型和测试需求,灵活组合不同类型的断言!
---
4.6.2 常见断言类型及用法
1.响应断言(Response Assertion)
功能:检查响应内容、响应头、状态码等是否符合条件。
适用场景:通用的文本或正则表达式匹配。
关键参数:
- Apply to:作用范围(主请求、子请求、JMeter变量等)。
- Field to Test:检查的字段(响应文本、响应头、响应代码等)。
- Pattern Matching Rules:匹配规则(包含、等于、正则表达式)。
- Patterns:匹配模式(支持多条件)。
示例:
- 验证状态码为200:

- 验证响应中包含 :"success"

2. JSON断言(JSON Assertion)
功能:验证JSON响应中的特定字段值。
适用场景:REST API返回JSON数据的校验。
关键参数:
- Assert JSON Path exists:JSON路径(如 `$.data.userId`)。
- Additionally assert value:是否验证字段值。
- Expected Value:期望的值(支持正则表达式)。
示例:
验证JSON中 `userId` 字段是否为数字:
```text
JSON Path = $.data.userId
Expected Value = \d+
Match as regular expression = true
```

3.持续时间断言(Duration Assertion)
功能:验证请求的响应时间是否在指定阈值内。
适用场景:性能测试中检查接口响应时间是否达标。
参数:
- Duration in milliseconds:最大允许的响应时间(单位:毫秒)。
示例:
设置最大响应时间为2000ms,超过则断言失败。

4.大小断言(Size Assertion)
功能:验证响应内容的大小(字节数)。
适用场景:检查响应是否过大或缺失。
参数:
- Size in bytes:期望的响应大小(支持 `>=`, `<=`, `=` 等条件)。
示例:
验证响应大小不超过10KB:
```text
Size in bytes = 10240
Type = <=
```

5. XML断言(XPath Assertion)
功能:通过XPath表达式验证XML响应内容。
适用场景:SOAP接口或XML格式响应的校验。
参数:
- XPath Expression:XPath表达式(如 `//book/price`)。
- Validate XML:是否验证XML格式正确性。
- Expected Value:期望匹配的值。
示例:
验证XML中 `price` 节点值大于50:
```text
XPath = //book/price
Expected Value = 50
Condition = >
```
6.BeanShell断言(BeanShell Assertion)
功能:通过编写BeanShell脚本自定义断言逻辑。
适用场景:复杂校验逻辑(如动态计算、多条件组合)。
参数:
- Script:BeanShell脚本,使用 `Failure` 和 `FailureMessage` 变量标记断言结果。
示例:
验证响应时间是否小于平均值的2倍:
```java
if (SampleResult.getTime() > 2 vars.get("avg_time")) {
Failure = true;
FailureMessage = "响应时间超出阈值!";
}
```
7. HTML断言(HTML Assertion)
功能:验证HTML格式是否正确(基于HTML语法规则)。
适用场景:网页内容格式校验。
参数:
- HTML Error Threshold:允许的最大HTML错误数。
- HTML Warning Threshold:允许的最大HTML警告数。
8.MD5Hex断言(MD5Hex Assertion)
功能:验证响应内容的MD5哈希值是否符合预期。
适用场景:确保响应内容未篡改(如文件下载)。
参数:
- MD5Hex:预期的MD5哈希值(32位十六进制字符串)。
4.6.3. 断言的使用方法
1. 添加断言:
- 右键点击需要验证的 Sampler(HTTP请求) → Add → Assertions → 选择断言类型。
2. 作用域:
- 断言默认作用于其父节点下的所有Sampler。
- 若在 线程组 下添加断言,则作用于该线程组的所有请求。
3. 查看结果:
- 使用【查看结构树】 View Results Tree 监听器查看断言失败的具体原因。
4.6.4. 最佳实践
- 精确匹配:优先使用 JSON断言 或 XPath断言 替代正则表达式,减少误判。
- 分层校验:
- 第一层:验证状态码(响应断言)。
- 第二层:验证关键业务字段(JSON/XPath断言)。
- 第三层:验证性能指标(持续时间断言)。
- 性能优化:
- 避免在压测时启用大量复杂断言(如BeanShell断言),可能影响测试性能。
- 动态数据:
- 使用正则表达式提取器或JSON提取器获取动态值,再通过断言验证。
4.6.5. 常见问题
- 断言不生效:
- 检查断言的作用域是否正确。
- 确保断言未配置在逻辑控制器(如If控制器)外部。
- 正则表达式匹配失败:
- 使用在线工具(如 [regex101.com](https://regex101.com))调试正则表达式。
- JSON路径错误:
- 使用浏览器插件(如 JSONPath Finder)验证JSON路径。
4.6.6. 示例场景
场景:登录接口校验
1. 响应断言:验证状态码为200。

2. JSON断言:验证 `"code": 0`。

3. 持续时间断言:响应时间 < 1000ms。

4. BeanShell断言:验证响应中的 `token` 不为空。

4.7 配置元件(Config Element)
4.7.1 配置元件的作用
配置元件用于预定义测试环境参数,如HTTP请求头、变量、数据库连接等,确保测试脚本的灵活性和可维护性。它们通常在线程组执行前加载。
4.7.2 常见配置元件及用法
1. HTTP请求默认值(HTTP Request Defaults)
功能:为所有HTTP请求设置默认值(协议、域名、端口等),减少重复配置。
适用场景:测试同一服务器的多个接口。
关键参数:
- Protocol:协议(HTTP/HTTPS)。
- Server Name/IP:服务器地址。
- Port Number:端口号(默认80/443可留空)。
示例:
设置 `Server Name = api.example.com`,后续HTTP请求只需填写路径(如 `/login`)。

2. CSV数据文件设置(CSV Data Set Config)
功能:从CSV文件中读取数据,实现参数化测试。
适用场景:多用户登录、动态数据请求。
关键参数:
- Filename:CSV文件路径(支持相对路径)。
- Variable Names:变量名(逗号分隔,对应CSV列名)。
- Delimiter:分隔符(默认逗号)。
- Recycle on EOF?:文件结束时是否循环读取。
示例:
CSV文件内容:
```csv
username,password
user1,pass123
user2,pass456
```
JMeter配置:
- Variable Names = `username,password`
在HTTP请求中使用 `${username}` 和 `${password}` 动态替换值。

3. HTTP信息头管理器(HTTP Header Manager)
功能:为HTTP请求添加公共请求头(如Content-Type、Authorization)。
适用场景:REST API测试需固定请求头。
关键参数:
- Headers:键值对形式的请求头(如 `Content-Type=application/json`)。
示例:
设置 `Authorization=Bearer ${token}`,用于需要Token验证的接口。

4. 用户定义的变量(User Defined Variables)
功能:定义全局或局部变量,简化脚本维护。
适用场景:配置环境相关参数(如不同环境的URL)。
关键参数:
- Variables:变量名和值的键值对。
示例:
定义 `base_url = http://dev.example.com`,在HTTP请求中使用 `${base_url}/api`。

5. Cookie管理器(HTTP Cookie Manager)
功能:自动管理Cookie(存储和发送),模拟浏览器行为。
适用场景:需要会话保持的测试(如登录后操作)。
关键参数:
- Clear cookies each iteration?:是否每次迭代清除Cookie。
示例:
登录后,Cookie管理器自动携带Session ID访问其他接口。
6. JDBC连接配置(JDBC Connection Configuration)
功能:配置数据库连接池,供JDBC请求使用。
适用场景:直接测试数据库性能或验证数据。
关键参数:
- Database URL:数据库连接字符串(如 `jdbc:mysql://localhost:3306/test`)。
- JDBC Driver Class:驱动类(如 `com.mysql.jdbc.Driver`)。
- Username/Password:数据库账号密码。
示例:
配置MySQL连接后,通过JDBC Request执行SQL查询。



7. 计数器(Counter)
功能:生成递增或递减的数字,用于动态参数(如订单号)。
适用场景:生成唯一值或循环序列。
关键参数:
- Starting Value:初始值。
- Increment:步长。
- Format:数字格式(如 `ORD_0001`),日期+计数:${__time(yyyyMMdd)}_000` → 生成 `20231001_001`, `20231001_002`。
-是否每个线程独立计数(勾选后,每个线程有自己的计数器副本)
-每次线程组循坏时重置计数器(仅当独立计数启用时有效)依赖于是否每个线程独立计数,不能单独勾选
示例:
生成订单号 `ORD_0001, ORD_0002...`,在请求中使用 `${order_id}`。


8. 随机变量(Random Variable)
功能:生成指定范围内的随机数或字符串。
适用场景:模拟随机输入(如用户ID、手机号)。
关键参数:
- Variable Name:变量名。
- Minimum/Maximum Value:随机数范围。
- Output Format:格式(如 `PHONE_${__Random(13000000000,19999999999,)}`)。
9. 登录配置元件(Login Config Element)
功能:为HTTP请求设置BASIC认证的用户名和密码。
适用场景:需要HTTP Basic认证的接口。
关键参数:
- Username/Password:认证信息。
4.7.3 最佳实践
1. 作用域管理:
- 配置元件的作用域为其父节点下的所有子元件。
- 将公共配置(如HTTP默认值)放在测试计划根目录,局部配置(如线程组专用变量)放在线程组内。
2. 参数化技巧:
- 使用 `${__P(variable)}` 从命令行动态获取变量(如环境切换)。
- 结合函数助手(`__Random`, `__time`)生成动态值。
3. 性能优化:
- 避免在压测时频繁读取大文件(如大型CSV),改用随机生成数据。
- 使用JDBC连接池时,合理配置最大连接数。
4.7.4 常见问题
- CSV文件读取失败:检查文件路径是否正确,或使用绝对路径。
- 变量未生效:确保变量名拼写一致,且作用域正确。
- 数据库连接超时:检查网络、驱动类及URL格式。
- Cookie未保存:确认Cookie管理器已启用,且未勾选“每次迭代清除”。
4.8、后置处理器
4.8.1、XPath提取器
路径:http请求 -> 添加 -> 后置处理器 -> XPath提取器

如:

语法规则:
(1) 基本路径表达式
| 表达式 | 说明 | 示例(JSON 响应) | 提取结果 |
|---|---|---|---|
$.key | 根节点下的字段 | {"name": "John"} | John |
$..key | 递归搜索所有层级的字段 | {"user": {"name": "John"}} | John |
$.array[n] | 数组的第 n 个元素(从 0 开始) | {"ids": [1, 2, 3]} | 2(n=1) |
$.array[*] | 数组的所有元素 | {"ids": [1, 2, 3]} | 1,2,3 |
$.key1.key2 | 嵌套字段 | {"user": {"name": "John"}} | John |
(2) 条件过滤
| 表达式 | 说明 | 示例 | 提取结果 |
|---|---|---|---|
$..[?(@.key==value)] | 过滤符合条件的对象 | {"users": [{"id":1}, {"id":2}]} | {"id":1}(@.id==1) |
$..[?(@.key>n)] | 数值比较 | {"prices": [10, 20, 30]} | 20,30(@>15) |
$..[?(@.key=~'/regex/')] | 正则表达式匹配 | {"names": ["John", "Jane"]} | John(/^J/) |
(3) 常用函数
| 函数 | 说明 | 示例 |
|---|---|---|
length() | 返回数组长度 | $.ids.length() |
min(), max() | 返回数组的最小/最大值 | $.prices.max() |
keys() | 返回对象的所有键名 | $.user.keys() |
4.8.2:正则表达式提取器
http请求 -> 添加 -> 后置处理器 -> 正则表达式提取器

(1) 基础匹配规则
| 表达式 | 说明 | 示例 |
|---|---|---|
(.*?) | 非贪婪匹配,匹配任意字符(最短内容)。 | name":"(.*?)" → 匹配 "name":"John" 中的 John |
(.*) | 贪婪匹配,匹配任意字符(最长内容)。 | 慎用,可能匹配到多余内容。 |
\d+ | 匹配数字(1次或多次)。 | id=(\d+) → 匹配 id=123 中的 123 |
\w+ | 匹配字母、数字、下划线(1次或多次)。 | user_(\w+) → 匹配 user_john 中的 john |
[a-zA-Z]+ | 匹配字母(大小写)。 | [A-Za-z]+ → 匹配 Abc |
\s | 匹配空白字符(空格、制表符等)。 |
(2) 常用元字符
| 元字符 | 说明 | 示例 | ||
|---|---|---|---|---|
. | 匹配任意单个字符(除换行符)。 | a.b → 匹配 aab、a1b | ||
^ | 匹配字符串开头。 | ^Start → 匹配以 Start 开头的行 | ||
$ | 匹配字符串结尾。 | end$ → 匹配以 end 结尾的行 | ||
| ` | ` | 或逻辑。 | `cat | dog→ 匹配cat或dog` |
\ | 转义字符。 | \$\d+ → 匹配 $100 |
4.8.3、边界提取器
边界规则
-
左/右边界需唯一:确保边界文本在响应中只出现一次,否则可能匹配错误。
-
支持转义字符:如
\n(换行)、\t(制表符)、\"(双引号)。 -
大小写敏感:默认区分大小写,需完全匹配边界文本。
示例1:提取JSON中的Token
-
响应数据:
json格式
{"token": "abc123", "expires": 3600} -
边界配置:
-
Left Boundary:
"token": " -
Right Boundary:
" -
Variable name:
api_token
-
-
提取结果:
abc123(存储在${api_token}中)

二、JMeter接口测试
1.接口测试基础
接口测试目标:功能验证、数据校验、异常处理。
常见协议:HTTP/HTTPS、REST、SOAP、WebSocket。
2.接口测试实战步骤
创建测试计划:添加线程组(单用户模拟功能测试)。
配置HTTP请求:URL、方法(GET/POST)、Header、Body(JSON/XML)。
-参数化与动态数据
- CSV文件参数化(CSV Data Set Config)。
- 正则表达式提取器(关联动态值,如Token)。
-断言与结果校验
- 响应状态码(200/404)。
- JSON Path/XPath断言(验证关键字段)。
-监听器与报告
- 查看结果树(调试用)。
- 聚合报告(统计成功率、响应时间)。
3.高级技巧
(1)数据驱动测试(结合外部文件或数据库)
(2)接口依赖处理(如登录后获取Token)
①设置为局部变量(线程组内其他接口使用)
根据后置处理器中的json提取器或者其他提取器获取登录token,设置变量名称为token,使用${token}进行其他接口的引用即可
②设置为全局变量(跨线程组关联)
步骤一、建立局部变量和全局变量的对应关系 (通过函数 __setProperty)

步骤二、导出为全局变量,添加BeanShell 取样器,注意:在获取token的接口请求后中添加

步骤三、把步骤一中生成的函数结果贴入BeanShell 取样器中

步骤四、其他线程组接口调用,通过函数 __Property)
直接调用 ${__property(全局变量名,,)} 即可

(3)集成到CI/CD(通过Jenkins + Maven执行)
三、JMeter压力测试
1.压力测试核心概念
目标:评估系统在高并发下的稳定性、瓶颈定位。
关键指标:TPS(每秒事务数)、响应时间、错误率、吞吐量。
2.压测场景设计
线程组配置:线程数(并发用户)、Ramp-Up时间、循环次数。
负载模型:阶梯加压(Stepping Thread Group插件)、峰值测试。
定时器:固定定时器、高斯随机定时器(模拟真实用户间隔)。
3.分布式压测
主从机配置:解决单机资源瓶颈。
执行步骤:修改`jmeter.properties`、启动Agent、远程运行。
3.1分布式压测原理
JMeter分布式测试架构包含:
-
主控机(Master):运行JMeter GUI(正常启动 jmeter.bat),控制测试计划分发
-
执行机(Slave):运行jmeter-server.bat,执行实际测试
3.2分布式压测前提条件
-
所有机器(主控机和执行机)必须:
-
安装相同版本的JMeter和Java
-
使用相同的测试计划文件
-
网络互通(建议关闭防火墙或开放相应端口)
-
-
执行机需要运行jmeter-server:
-
Windows:运行
jmeter-server.bat -
Linux/Mac:运行
jmeter-server
-
3.3分布式压测配置步骤
1. 执行机配置
-
修改执行机的
jmeter.properties文件:server.rmi.ssl.disable=true # 禁用SSL(测试环境可用,生产环境建议启用) server_port=1099 # 默认端口
-
启动执行机的jmeter-server:
# Linux/Mac ./jmeter-server # Windows jmeter-server.bat
2. 主控机配置
-
修改主控机的
jmeter.properties文件:remote_hosts=192.168.1.101:1099,192.168.1.102:1099 # 执行机IP列表 server.rmi.ssl.disable=true # 与执行机一致
-
可选:设置主控机也参与测试(默认不参与):
mode=Standard # 主控机仅控制 mode=Server # 主控机也参与测试
3.4执行分布式测试
方法1:通过GUI启动
-
在主控机打开JMeter GUI
-
打开测试计划文件
-
运行 → 远程启动 → 选择单个执行机或"全部启动"
方法2:通过命令行启动
jmeter -n -t testplan.jmx -l result.jtl -R 192.168.1.101,192.168.1.102
参数说明:
-
-n:非GUI模式 -
-t:测试计划文件 -
-l:结果文件 -
-R:执行机列表(用逗号分隔)
4.阶梯式加压
作用:阶梯式压测(Stepped Load Test)是一种逐步增加负载的测试方法,可以观察系统在不同压力级别下的表现,帮助识别性能拐点和系统瓶颈。
比如加压时长为25秒,分五次加压,每次加压持续时长为5秒,达到并发数后,进行一段一分钟的稳压
步骤一:添加线程组
使用bzm - Concurrency Thread Group线程组:设置如下
注意:需要压测的接口配置在该线程组下

步骤二、配置资源监控
jp@gc - PerfMon Metrics Collector监听器

如何找出最佳用户数和最大用户数
刚开时,响应时间是走势是比较缓慢的延长(相对较快),占用的资源比较少,吞吐量在慢慢增加,此时属于轻压区,随着用户数的不断增加,达到一定数量后,开始进入重压区,这个分界点就是最佳用户数,当响应时间越来越长,持续走高,占用资源基本不太变化,吞吐量开始减少时,此时进入崩溃区,这个临界点算是最大用户数

也可以添加监听器:
-
聚合报告
-
响应时间图
-
Active Threads Over Time(观察线程增长)
-
Transactions per Second(TPS)
5.监控与分析
服务器资源监控(CPU/内存/磁盘IO):通过PerfMon插件。
JMeter监听器:
- 聚合报告(平均响应时间、TPS)。
- 响应时间图、TPS曲线图。
结果分析:
- 定位性能瓶颈(数据库慢查询、代码低效)。
- 优化建议(缓存、连接池、代码异步化)。
6.压测性能参考指标和性能基线定义
6.1设置关键指标参数
一、核心定义
1. TPS:Transactions Per Second(每秒事务数)
- 核心定义:系统每秒能成功完成的 “完整业务事务” 数量,是衡量系统「业务处理能力」的核心指标(偏 “业务维度”)。
- 关键前提:“事务” 是预定义的「业务闭环」,必须包含 “请求发起→业务逻辑执行(可能含多步操作)→数据持久化→响应返回” 的完整流程,且结果为 “成功”(失败的事务不计入有效 TPS)。
- 示例:
- 电商下单:“提交订单→扣减库存→生成支付单→返回下单结果” 为一个事务,1 秒内成功完成 100 次该流程,则 TPS=100。
- 银行转账:“校验余额→扣减转出账户→增加转入账户→记录流水” 为一个事务,1 秒成功处理 50 次,则 TPS=50。
- 特点:强业务关联性,不同业务的 “事务” 复杂度差异极大(如下单 vs 简单查询),因此 TPS 无法跨业务直接对比。
2. QPS:Queries Per Second(每秒查询数)
- 核心定义:系统每秒能处理的「查询类请求」数量,聚焦 “单次请求的处理能力”(偏 “技术维度”,不限定 “只读”,但默认是轻量查询)。
- 关键前提:统计的是「单次独立请求」(无论读 / 写,但通常以查询、接口调用等轻量操作为主),不要求 “业务闭环”,仅关注 “请求接收→处理→响应返回” 的过程(成功的请求计入,部分场景会统计 “总查询数” 含失败,但默认是有效查询)。
- 示例:
- 商品详情查询:用户请求 “获取某款手机的价格、库存、参数”,1 秒内系统成功响应 1000 次,则 QPS=1000。
- 登录接口调用:用户请求 “校验账号密码并返回 token”,1 秒成功处理 800 次,则 QPS=800。
- 特点:技术导向,聚焦 “单次请求的处理效率”,可跨场景对比(如不同接口、不同系统的单次请求处理能力),是性能测试中最常用的 “基础指标”。
3. 吞吐量(Throughput)
- 核心定义:系统在单位时间内处理的「总数据量或总请求数」,是衡量系统「整体承载能力」的宏观指标(偏 “全局维度”),统计口径可灵活定义。
- 常见统计口径(必须明确说明,否则易混淆):
- 数据量维度:每秒传输的字节数(KB/s、MB/s),如接口返回数据总大小、数据库读写数据量、文件传输量。
- 请求数维度:每秒处理的「所有请求总数」(含成功 / 失败、查询 / 写操作、事务内 / 外的请求),不区分请求类型和结果。
- 示例:
- 数据量吞吐量:某视频服务器 1 秒内传输视频文件总大小为 200MB,则吞吐量 = 200MB/s。
- 请求数吞吐量:某接口 1 秒内接收 1200 次请求(其中成功 1000 次、失败 200 次),则吞吐量 = 1200 req/s。
- 特点:宏观性、口径灵活,是系统 “整体承载能力” 的体现,不绑定具体业务或操作类型,常用来衡量服务器、数据库、网络的整体性能上限。
二、核心区别(4 个维度清晰对比)
| 对比维度 | TPS(每秒事务数) | QPS(每秒查询数) | 吞吐量(Throughput) |
|---|---|---|---|
| 聚焦场景 | 完整业务闭环(可能包含多步请求) | 单次独立请求(轻量操作为主) | 所有操作 / 数据传输(全局无差别) |
| 统计口径 | 仅成功完成的「业务事务」 | 通常是成功的「单次请求」(部分场景含失败) | 总请求数(成功 + 失败)或总数据量 |
| 业务关联性 | 强(依赖业务定义的 “事务”) | 弱(仅关注单次请求,与业务解耦) | 极弱(宏观指标,无业务绑定) |
| 核心用途 | 衡量业务核心流程能力(下单、支付) | 衡量单次请求处理效率(接口、查询) | 衡量系统整体承载上限(带宽、并发、存储) |
关键区分点(避免踩坑):
- TPS vs QPS:“业务闭环” vs “单次请求”
- 一个 TPS 可能包含多个 QPS:比如 “下单事务” 可能包含 “查询库存(1 次 QPS)+ 扣减库存(1 次 QPS)+ 生成订单(1 次 QPS)”,因此TPS ≤ 相关 QPS 之和(实际中因事务内步骤有依赖,TPS 会远小于 QPS)。
- 例:电商系统中,商品查询 QPS 可能达 10000,但下单 TPS 可能仅 500(下单事务包含多个 QPS,且有数据锁、逻辑校验等开销)。
- TPS/QPS vs 吞吐量:“有效能力” vs “整体上限”
- TPS 和 QPS 是 “细分场景的有效处理能力”(只统计成功的、目标场景的操作);吞吐量是 “整体处理能力”(统计所有操作,含失败、无效请求)。
- 因此:吞吐量 ≥ TPS 且 吞吐量 ≥ QPS(比如 QPS=1000,可能有 200 次失败请求,此时吞吐量 = 1200 req/s)。
- 口径灵活性:吞吐量最灵活,TPS 最固定
- 吞吐量可按 “数据量” 或 “请求数” 统计(需在测试报告中明确);QPS 仅按 “请求数” 统计;TPS 仅按 “业务事务数” 统计(口径固定,需先定义清楚 “事务范围”)。
三、关联关系(相互支撑,而非独立)
三者是 “整体→局部”“宏观→微观”“业务→技术” 的递进关系,核心关联如下:
1. 吞吐量是 TPS 和 QPS 的 “上限容器”
- 系统的吞吐量(请求数维度)决定了 TPS 和 QPS 的最大可能值:吞吐量(req/s)= 成功请求数(QPS + 其他写操作请求数)+ 失败请求数因此:QPS ≤ 吞吐量,TPS ≤ 吞吐量(因为 TPS 对应的事务本质是 “多步 QPS 的组合”)。
- 例:若服务器吞吐量(请求数)为 5000 req/s,其中商品查询 QPS=3000(成功),下单事务对应的 QPS 之和 = 2000(成功),失败请求 = 500,则吞吐量 = 3000+2000+500=5500 req/s(符合 “吞吐量≥QPS+TPS 相关请求数”)。
2. TPS 依赖 QPS 的支撑,QPS 是 TPS 的基础
- 任何业务事务(TPS)都需要通过多个单次请求(QPS)实现,因此 QPS 的性能直接影响 TPS:
- 若 QPS 过低(比如查询库存的 QPS 仅 300),即使其他步骤性能再好,下单事务的 TPS 也无法超过 300(因为库存查询是瓶颈)。
- 优化 QPS(如缓存优化、接口性能优化),通常会间接提升 TPS(减少事务内步骤的处理时间)。
3. 吞吐量受 TPS/QPS 和数据量共同影响
- 当请求的数据量较大时(如返回大文件、大量列表数据),吞吐量(数据量维度)会成为瓶颈,进而限制 QPS 和 TPS:
- 例:某接口返回数据量为 1MB / 次,若服务器带宽仅 100MB/s,则最大 QPS=100(100MB/s ÷ 1MB / 次),即使接口处理逻辑再快,QPS 也无法突破 100,进而限制依赖该接口的 TPS。
四、实际测试中的应用场景(避免用错指标)
- 关注业务核心能力时,看 TPS
- 比如测试 “下单、支付、转账” 等核心流程,需以 TPS 为核心指标(直接反映业务能支撑的并发用户数),同时搭配响应时间、错误率。
- 关注接口 / 查询效率时,看 QPS
- 比如测试 “商品列表查询、用户信息查询、登录接口” 等单次请求,用 QPS 衡量处理效率,搭配响应时间(如 P95/P99 延迟)。
- 关注系统整体承载能力时,看吞吐量
- 比如测试 “服务器带宽上限、数据库读写总能力、文件传输速度”,用吞吐量(数据量或请求数维度)衡量,搭配资源使用率(CPU、内存、带宽)。
经典误区纠正:
- 误区 1:“QPS=TPS”→ 仅当 “一个事务 = 一个单次请求” 时成立(如简单查询事务),复杂业务中 TPS 远小于 QPS。
- 误区 2:“吞吐量越高,TPS/QPS 越好”→ 若吞吐量高但失败率高(如吞吐量 = 1000 req/s,失败率 50%),实际有效 QPS=500,无意义。
- 误区 3:“跨业务对比 TPS”→ 不同业务的事务复杂度不同(如下单 vs 登录),TPS 数值无对比价值,需对比 “同业务的 TPS 提升比例” 或 “TPS / 资源使用率”。
总结
- TPS:业务视角的 “有效处理能力”,聚焦完整闭环;
- QPS:技术视角的 “单次请求效率”,聚焦独立操作;
- 吞吐量:全局视角的 “整体承载上限”,聚焦总量 / 数据量;三者的核心逻辑:吞吐量提供上限,QPS 支撑 TPS,TPS 反映业务最终能力。在性能测试中,需根据测试目标选择核心指标,同时搭配其他指标(响应时间、错误率、资源使用率)才能全面评估系统性能。
4.平均响应时间:看聚合报告的平均值,单位秒
5.错误率:看聚合报告的异常百分比
6.2定义性能标准
①吞吐量(Throughput):经过计算达到要求,28原则进行计算(80%的业务在20%的时间内完成)
例1:某网站每日的总访问人数为10w, 其中搜索业务占20%, 浏览商品占30%, 登录+购买业务占50% (每天按8小时计算), 计算服务器应达到的吞吐量
计算:
搜索业务:(100000*20%*80%)/(8*3600*20%)=2.78取整为3请求数/秒
浏览商品页:(100000*30%*80%)/(8*3600*20%)=4.17取整为5请求数/秒
登录+购买:(100000*50%*80%)/(8*3600*20%)=6.94取整为7请求数/秒
例2:系统每年的业务集中在8个月完成, 每个月平均有20个工作日, 每个工作日8小时
去年全年处理业务约100万笔
其中15%的业务处理中每笔业务需对应用服务器提交7次请求
其中70%的业务处理中每笔业务需对应用服务器提交5次请求
剩余15%的业务处理中每笔业务需对应用服务器提交3次请求
根据以往的统计结果, 每年的业务增长量为15%
考虑到今后3年的业务发展需要, 测试需按现有业务量的两倍进行计算
请求总数=(100万*15%*7+100万*70%*5+100万*15%*3)*2=1000万
吞吐量=(10000000*80%)/(8*20*8*3600*20%)=8.68取整为9
②平均响应时间:对比同类产品以及用户体验,同时参考3,5,8原则
③错误率:99.99%-100%
④各种硬件指标:服务器cpu和内存占用率不超过80%
6.3标准定好后定义性能基线
在满足性能标准的情况下,连续压测系统15次以上,各个标准取平均值,得到性能指标参考基线,后续版本压测时,如果性能指标跌涨幅度超过多少就需要进行分析定位
四、常见问题与解决方案
1.内存溢出
调整JVM参数(`HEAP=-Xms2g -Xmx4g`)。
2.参数化失败
检查CSV文件编码、路径是否正确。
3.压测结果不准确
禁用GUI模式、使用命令行执行(`jmeter -n -t test.jmx -l result.jtl`)。
4.分布式测试问题
确保防火墙关闭、主从机版本一致。
5.cpu高负载
5.1常见原因
①应用代码效率问题:
- 存在死循环或复杂算法
- 低效的数据库查询
- 未优化的业务逻辑
②资源竞争:
- 线程锁竞争激烈
- 连接池资源耗尽
③配置不当:
- JVM堆内存设置不合理
- 线程池配置过大
5.2诊断方法
-
获取线程堆栈:
bash
# 对于Java应用 jstack <pid> > thread_dump.log # 或使用jcmd jcmd <pid> Thread.print > thread_dump.log
-
分析CPU高的线程:
bash
top -H -p <pid> # Linux查看线程级CPU使用
-
使用Profiler工具:
-
Arthas
-
JProfiler
-
VisualVM
-
5.3解决方法:
-
代码优化:
-
优化高频执行的代码路径
-
减少同步锁范围
-
使用缓存减少重复计算
-
-
数据库优化:
-
添加缺失的索引
-
优化SQL语句
-
增加查询缓存
-
-
配置调整:
-
合理设置JVM参数
-
调整线程池大小
-
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)