📑 目录
- [1. 什么是性能测试](#1. 什么是性能测试)
- [2. 常见的性能测试指标](#2. 常见的性能测试指标)
- [3. 性能测试分类](#3. 性能测试分类)
- [基准测试(Baseline Testing)](#基准测试(Baseline Testing))
- [负载测试(Load Testing)](#负载测试(Load Testing))
- [压力测试(Stress Testing)](#压力测试(Stress Testing))
- [并发测试(Concurrency Testing)](#并发测试(Concurrency Testing))
- [稳定性/疲劳测试(Endurance/Soak Testing)](#稳定性/疲劳测试(Endurance/Soak Testing))
- [容量测试(Capacity Testing)](#容量测试(Capacity Testing))
- [4. 如何开展性能测试](#4. 如何开展性能测试)
- 1) 安装JMeter并配置中文 安装JMeter并配置中文)
- 2) 使用JMeter对博客系统性能测试 使用JMeter对博客系统性能测试)
- 3) 安装JMeter插件 安装JMeter插件)
- 4) 对接口进行梯度压测 对接口进行梯度压测)
1.什么是性能测试
是为了发现系统性能问题或获取系统性能相关指标而进行的测试.一般都是功能测试在前,性能测试在后.
2.常见的性能测试指标
并发用户数(Concurrent Users):
同一时刻向系统发起请求或与系统进行交互的虚拟用户数量。
吞吐量与 TPS/QPS:
- 吞吐量 :每秒能够处理的并发数,能直接体现软件系统负载承受能力。吞吐量越高,系统承受的并发越多,性能越好。
- TPS(Transactions Per Second): 每秒能够处理的事务数,是衡量后端综合处理能力的核心指标。
- QPS(Queries Per Second): 每秒能处理的==查询/请求数 ==。
若一个事务中只有一个接口且是查询接口,则QPS = TPS
响应时间:
从客户端发起请求到收到服务器完整响应 所消耗的时间.
对于Web系统而言,系统响应时间包括前端展现时间 和系统响应时间.
系统性能模型曲线图
展示了并发用户数 、系统吞吐量(TPS) 与 系统响应时间(RT) 之间的动态演变规律。

坐标轴与关键指标含义
- 横坐标( V U VU VU / Server Resource): 虚拟并发用户数(Virtual Users)以及服务器硬件资源(CPU、内存等)的消耗程度,从左至右不断递增。
- 纵坐标( T P S TPS TPS): 系统每秒处理的事务数(吞吐量),反映系统的处理能力。
- 曲线趋势: 描述随着并发压力增加,系统吞吐量经历的"上升 → \rightarrow → 达到顶峰 → \rightarrow → 骤降"完整周期。
- 最佳工作范围: 阴影区域( A x ∼ C x A_x \sim C_x Ax∼Cx)是系统最理想的生产运行负载区间。
对应的系统响应时间图:

在性能测试中的意义: - 日常容量规划: 将日常高频业务负载控制在 A x ∼ B x A_x \sim B_x Ax∼Bx 区间,保证系统轻快运行。
- 峰值负载上限: 业务峰值(如促销活动)的极限并发不能超过 c 点( C x C_x Cx),需预留安全水位,防止系统越过拐点坠入过饱和区。
- 瓶颈定位: 压测的核心目标之一就是通过逐步加压,精准找到最高点 c 点.
资源利用率
服务器端的硬件消耗情况,包括 CPU 使用率、内存占用、磁盘 I/O 读写以及网络带宽占用。
3.性能测试分类
基准测试(Baseline Testing):
- 定义:在系统单用户或极低压力环境下运行的测试。
- 目的:建立系统的初始性能基线数据,作为后续多用户并发及混合测试的对比参考。
负载测试(Load Testing):
- 定义 :在满足各项性能指标(如响应时间 ≤ 2 \le 2 ≤2 秒、错误率 < 0.1 % < 0.1\% <0.1%)的安全前提下,逐步增加系统负载。
- 目的 :探测系统在正常运行标准下所能承受的最大安全负载量(最佳性能容量)。
压力测试(Stress Testing):
- 定义:持续对系统施加超出正常承载能力的极端负载,或在极端资源匮乏(CPU/内存占满、网络受限)的条件下运行。
- 目的:寻找系统的性能拐点与崩溃极限,测试系统在超负荷下的降级策略、容错能力及故障恢复表现。
**并发测试(Concurrency Testing):
- 定义:模拟多个虚拟用户在同一绝对时间点同时执行特定操作(如秒杀、集中登录)。
- 目的:检验系统对瞬间高并发请求的处理能力,主要用于发现死锁、资源竞争、内存泄漏等并发安全问题。
稳定性/疲劳测试(Endurance/Soak Testing):
- 定义:在一定的正常或较高负载压力下,让系统连续不间断运行较长时间(如 24 小时、3×24 小时甚至数周)。
- 目的:验证系统在长期运行过程中是否存在缓慢内存泄漏、句柄未释放、连接池耗尽或性能衰减等隐蔽缺陷。
容量测试(Capacity Testing):
- 定义:结合数据库数据量(如亿级数据表)、硬件规格与用户访问规模开展的测试。
- 目的 :确定系统在特定硬件配置与数据量级下能够支持的最大业务容量,为后续架构扩容与硬件采购提供数据支撑。
小结 :
负载测试 关注的是"指标合格下的最大承载量 "(能安全扛多少)。
压力测试 关注的是"把系统压到极限甚至崩溃"(什么时候挂、怎么挂)。
4.如何开展性能测试
使用Apache JMeter工具,对软件做性能测试.
环境要求:Java8或更高
1)安装JMeter并配置中文
JMeter下载官网:https://jmeter.apache.org/download_jmeter.cgi

下载完后解压:

解压完成后:
找到解压后的文件夹,找到该文件夹下的bin目录,并将该路径复制下来,随后要将该路径配置进系统环境变量.

配置系统环境变量:

打开JMeter:
通过cmd命令行,输入JMeter即可打开.


配置中文:


在jmeter的bin目录下,修改文件中的内容:language=zh_CN
2)使用JMeter对博客系统性能测试
需要测试的接口:
\[接口自动化测试(HTTP API测试)#2.挑选接口\]
准备工作:
启动并打开JMeter,在"测试计划"下添加"线程组".

可以自定义线程组的名称,这样更能贴近实际业务场景.
登录接口性能测试:
接下来就能进行接口的性能测试了
- 首先需要在"线程组"下添加一个"HTTP请求取样器".进行博客登录接口的测试:

填写好登录接口对应的数据,注意请求参数是JSON格式还是表单格式的数据.
- 如果是 JSON:Header 里写
Content-Type: application/json - 如果是表单:Header 里写
Content-Type: application/x-www-form-urlencoded或 `multipart/form-data
由于JMeter 默认不会自动添加请求头 ,所以需要自行添加==HTTP信息头管理器 ==

- 在"博客登录接口测试取样器"下添加"信息头管理器",并填写Header对应的参数,由于登录接口请求的参数是JSON格式的,所以Header 里写
Content-Type: application/json.


- 最后还要在"博客系统接口性能测试"线程组下添加"查看结果树 "监听器,就能完成对该接口的一次性能测试了.

- 点击"启动"按钮运行,查看接口测试结果

f.CSV数据文件设置
当我们执行登陆接口的性能测试时,手动配置了用户名和密码为固定的username和password,然而实际使用中不可能只有一个用户登陆,为了模拟更真实的登录环境,我们需要提供更多的用户username和password来实现登录操作,可以将username和password配置在CVS文件中,然后添加一个配置元件"CVS数据文件设置",就能模拟更真实的登录环境了.
操作步骤:
- 打开excel表格,填写上username和passwoed.填写好后要保存为.csv的文件格式.

- CSV数据⽂件设置

- 文件名:填写csv文件的路径。建议使用绝对路径。
- 文件编码:UTF-8
- 变量名称:从csv数据文件中读起的数据需要保存到的变量名。有多个变量时用逗号分隔
- 是否忽略首行:是否从csv数据文件第一行开始读取。
- 分隔符:要求与csv数据文件中多列的分隔符一致
- 遇到文件结束符再次循环:若选择为True当数据不够的时候会从头取。若选择False,则需要勾选下面的配置,遇到文件结束符停止线程,这里如果不勾选,请求将会报错。
- 修改登陆接口及其他涉及到username和password获取的参数

修改完该配置后,登陆接口发起请求时将从csv文件中获取配置好的username和password参数,获取顺序为从上往下依次获取.
执行测试:

JMeter重要组件说明:
a.线程组

-
线程数 = 模拟的虚拟用户数量(Virtual Users),但是线程数并不等于真实用户。
-
Ramp-Up = 所有线程启动完成需要的时间。如果Ramp-Up = 0,表示线程全部同时启动,适合:适合测试:瞬间高并发以及秒杀场景.
-
循环次数:每个线程执行测试计划多少次。
用户1:
请求流程 ×10
用户2:
请求流程 ×10
...
用户6:
请求流程 ×10
总执行次数:
线程数 × 循环次数
=6×10
=60次
- 永久勾选后,循环次数失效,线程会一直运行,直到手动停止或达到调度时间,常用于压力测试.
- Same user on each iteration (每次循环使用相同用户),与Cookie、Session 有关。勾选上 ,每次循环测试登录的用户都是一样的,也就是会保持登录的状态.不勾选 ,每次循环测试登录的用户都需要重新登录,适合模拟不同用户访问的测试.
- 延迟创建线程直到需要 :默认是JMeter启动时,提前创建线程。勾选后,需要执行时才创建。优点:减少资源占用。适合:大规模压力测试
- 调度器 :勾选后:启用定时运行.填写下面至少一个参数后生效:
- 持续时间:表示运行多久.
- 启动延迟:延迟多久开始.
记忆口诀:
| 参数 | 记忆 |
|---|---|
| 线程数 | 多少用户 |
| Ramp-Up | 多久把用户拉起来 |
| 循环次数 | 每个用户做几遍 |
| Forever | 一直做 |
| 调度器 | 什么时候开始、运行多久 |
| 持续时间 | 压力持续多久 |
| 启动延迟 | 多久后开始 |
b.HTTP取样器

填写好对应的参数.
| 参数 | 作用 |
|---|---|
| 协议 | 用HTTP还是HTTPS |
| 服务器IP | 请求发给谁 |
| 端口 | 服务器哪个入口 |
| 方法 | GET/POST/PUT |
| 路径 | 调用哪个接口 |
| 参数 | URL参数 |
| 消息体 | POST提交的数据 |
| KeepAlive | 是否保持连接 |
| multipart | 文件上传 |
| 编码 | 字符格式 |
c.查看结果树

取样器结果:统计请求相关的信息
- Thread Name: 线程组名称
- Sample time:发送请求时间
- load time: 响应时间
- Response code : 接口响应状态码
请求 :HTTP请求的请求头和请求体的详细信息
响应:HTTP响应的响应头和响应体的详细信息
博客列表页接口测试:
- 首先需要在"线程组"下添加一个"HTTP请求取样器".并将其名称改为:博客列表页接口.

红色线条圈出来的区域对于要测试的每个接口来说都是一样的,每次填写取样器时都需要填写,显得很麻烦.于是我们可以在"线程组"下添加一个"HTTP请求默认值"配置元件,填写好对应的参数,因为它的位置在线程组下,即对每一次HTTP请求都有效,就不用我们每次填相同的参数了.


- 获取博客列表页请求时需要登录凭证,所以需要添加一个在"线程组"下添加一个"HTTP信息头管理器",因为除登录接口以外,其他的接口,都需要登录凭证,所以"HTTP信息头管理器"添加到全局下,作用全局.

由于每次登录的User-Token都会改变,所以我们不能填写固定的User-Token,JMeter提供了"JOSN提取器"后置处理器,可以用于提取接口返回的JOSN数据,由于可以将登录接口返回的JSON响应信息中的token提取出来,作为其他接口的参数配置.
d.JSON提取器
从接口响应的 JSON 数据中提取指定字段的值,并保存成 JMeter 变量,供后续请求使用
I.添加JSON提取器
针对博客登录接口添加"JSON提取器"

JSON操作符参考:
| Operator | Description |
|---|---|
$ |
表示根元素 |
@ |
当前元素 |
* |
通配符。所有节点 |
.. |
选择所有符合条件的节点 |
.<name> |
子元素 |
['<name>' (, '<name>')] |
括号表示子元素或子元素列表 |
[<number> (, <number>)] |
数组索引或索引列表 |
[start:end] |
数组切片操作符 |
[?(<expression>)] |
过滤器表达式。表达式必须评估为布尔值。 |
II.添加JSON配置

我们需要提取的JSON数据是User-Token,因此可以将变量命令为token,对于JSONPath 表达式(告诉 JMeter 从 JSON 哪个位置取数据),需要到"查看结果树"对应接口的响应中验证一下.


III.配置JSON提取参数

这样User-Token字段对应的值就是随登录接口返回的token动态变化了.
e.JSON断言
接口发送请求成功,响应码为200并不能完全代表接口请求成功,我们更多关注接口响应数据是否符合预期.
就比如我们怎么知道登录接口返回的token数据是否正确,所以需要JSON断言一下才更安全.因此,在博客登录接口测试下添加一个"JSON断言".

关于\[正则表达式规则],因为token很长很长,但是token的前几个字符(eyJh)都是一样的,所以正则表达式可以设置为:^eyJh\S{100,}

最后测试一下博客列表页接口返回的响应是否符合预期:

获取作者详情接口:

该接口需要指定blogId和用户登录凭证,用户登录凭证前面已经添加了"HTTP信息头管理器",当中已包含token信息,现在需要关注的是blogId,可以传静态的值,但是如果该blogId的博客被删除,就会失败,因此可以像提取token一样,在列表页中提取有效的blogId.
获取登录用户信息接口:
该接口需要指定userId和用户登录凭证,用户登录凭证前面已经添加了"HTTP信息头管理器",当中已包含token信息,现在需要关注的是userId,传入的userId还需要与token信息对应上,所以在登录接口的响应中提取出userId.然后作为本接口的userId的字段值.

后面的接口测试,都是如法炮制,与上面的思路类似,不在赘述.
g.同步定时器
在性能测试过程中,为了真实模拟多个用户同时进行操作以度量服务器的处理能力,可以使用同步定时器 来设置集合点。不过,虽然通过加入集合点可以约束请求同时发送,但不能确保请求同时到达服务器 ,所以只能说是较真实模拟并发。



h.事务控制器
用于模拟用户进行一系列操作的测试。
在进行页面性能测试或API性能测试时,事务控制器是一个非常重要的工具。它可以帮助测试人员更准确地评估系统性能,尤其是在涉及多个接口或操作的复杂场景中。例如,在订单提交的过程中,可能需要调用多个接口,并且某些接口可能依赖于前一个接口的结果。在这种情况下,使用事务控制器可以将这些接口统一视为一个事务进行性能测试,从而得到更接近真实场景的性能测试结果。
比如将用户登录和获取列表页当成一个事务来处理.需要先添加一个事务处理器.

在将用户登录取样器和获取列表页取样器拖到事务控制器中,就是一个登录查询事务了.

3)安装JMeter插件:
下载链接 :https://jmeter-plugins.org/install/Install/

将下载好的插件放到jmeter下lib/ext文件夹下:

此时,jmeter界面右上角将会展示一个小蝴蝶形状的工具,该工具即jmeter插件功能,点击该功能可以下载jmeter中支持的各种插件:

在真实企业压测场景中,我们通常为一点一点的逐步增加线程数,因此需要安装新的插件来支持线程数的配置。
通过插件管理工具下载其他插件:
a.在插件中下载其他监听器插件


b.在插件中下载线程组插件

点击Apply Changes and Restart JMeter进行下载,下载完成后,JMeter会自动重启.
下载完成后即可添加梯度压测线程组(Stepping Thread Group)对接口梯度压测.

增强型监听器 插件:

- jp@gc - Active Threads Over Time:
活跃线程随时间变化监听器,作用:观察当前有多少虚拟用户正在运行。 - jp@gc - Response Times Over Time:
响应时间随时间变化,作用:查看接口响应时间随着压测时间如何变化。主要关注:平均响应时间,P95.
例如 :P95=800ms
表示:95%的请求小于800ms。 - jp@gc - Transactions per Second
每秒处理多少业务请求.发现用户增加,但TPS下降时,就说明达到了性能瓶颈. - jp@gc - PerfMon Metrics Collector
服务器性能监控采集器(监控被压服务器) - jp@gc - Flexible File Writer
灵活文件输出器,把测试结果保存成文件。 - jp@gc - Page Data Extractor
页面数据提取器.
| 监听器 | 作用 | 性能测试关注 |
|---|---|---|
| Active Threads Over Time | 线程数量变化 | 压力是否符合计划 |
| Response Times Over Time | 响应时间趋势 | 系统是否变慢 |
| Transactions per Second | TPS趋势 | 系统吞吐能力 |
| PerfMon Metrics Collector | 服务器资源 | CPU/内存/IO瓶颈 |
| Flexible File Writer | 保存结果 | 后续分析 |
| Page Data Extractor | 页面数据提取 | 参数关联 |
4)对接口进行梯度压测
什么是梯度压测?
梯度压测是通过逐步增加系统负载,在不同压力等级下观察系统的响应时间、吞吐量、错误率以及 CPU、内存、数据库 等资源指标,从而分析系统性能变化趋势,找到性能拐点、瓶颈以及系统在满足业务性能指标条件下的最大承载能力 。
比如:
| 并发用户 | 平均响应时间 | TPS | CPU | 错误率 |
|---|---|---|---|---|
| 100 | 120ms | 800 | 30% | 0% |
| 200 | 130ms | 1500 | 40% | 0% |
| 300 | 150ms | 2100 | 50% | 0% |
| 400 | 180ms | 2700 | 60% | 0% |
| 500 | 250ms | 3000 | 70% | 0% |
| 600 | 450ms | 3100 | 85% | 0.2% |
| 700 | 900ms | 3000 | 95% | 3% |
| 800 | 2500ms | 2200 | 100% | 15% |
| 你会发现压力逐渐增加, TPS逐渐增加后逐渐趋于平稳最后下降, 响应时间开始明显增加, 错误率开始增加, 系统达到瓶颈. |
为什么要做梯度压测?
为了找到系统性能拐点.
如何开展梯度压测?
- 首先添加一个"梯度测试线程组".

- 配置好对应的参数:

- This group will start: 启动多少个线程,同线程组中的线程数
- First, wait for: 等待多少秒才开始压测,一般默认为0
- Then start: 一开始有多少个线程数,一般默认为0
- Next,add: 下一次增加多少个线程数
- threads every: 当前运行多长时间后再次启动线程,即每一次线程启动完成之后的的持续时间;
- using ramp-up:启动线程的时间;若设置为5秒,表示每次启动线程都持续5秒
- then hold load for: 线程全部启动完之后持续运行多长时间
- finally,stop/threadsevery : 多长时间释放多少个线程;若设置为5个和1秒,表示持续负载结束之后每1秒钟释放5个线程
上面所配置参数的含义是:启动20个线程,等待0秒开始压测,一开始没有线程,下一次在3之内增加5个线程,当5个线程启动后,再运行5秒,再次启动线程,线程全部启动之后,在持续运行80秒,之后每相隔1秒释放5个线程.
- 然后再将博客系统的接口信息拷贝到当前线程组下

- 之后在当前线程组添加监视器

查看结果树 :在接口调试阶段使用.
聚合报告 :从聚合报告可以看到性能测试过程中整体的数据变化
Transactions per Second(TPS) :分析系统吞吐量,反应系统在同一时间内处理业务的最大能力.
Response Times Over Time :监听整个事务运行期间的响应时间,如果响应时间在某个时间点突变,就可能存在性能瓶颈.
Active Threads Over Time:查看用户活跃变化情况,看看变化是否符合最初在梯度线程组中的设定. - 最后启动执行.
- 执行完之后,生成性能测试报告.
生成性能测试报告的命令:
python
Jmeter -n -t 脚本⽂件 -l ⽇志⽂件 -e -o ⽬录
-n : ⽆图形化运⾏
-t : 被运⾏的脚本
-l : 将运⾏信息写⼊⽇志⽂件,后缀为jtl的⽇志⽂件
-e : ⽣成测试报告
-o : 指定报告输出⽬录
python
#先创建一个存放测试报告的文件夹,必须是空文件夹,否则会报错
mkdir report
jmeter -n -t 博客系统接口性能测试.jmx -l api_test_log.ctl -e -o report/.


双击index.html文件,界面展示如下:

最后进行性能分析 :
1 响应时间
如果响应时间超过了要求,代表系统到了瓶颈
注意事项:分析在多少线程的情况下发生了超时
响应时间变化的原因:
- 系统不稳定,有时快有时慢
- 随着并发压力变大而慢慢变慢,响应时间变高
2 错误率(可靠性)
高并发场景下,系统是否能够正常处理业务
要求:99.99%可靠,99.9999%
错误率高的原因:
- 接口请求错误
- 服务器无法继续处理,达到了瓶颈(代码写的不行,内存泄漏、硬件资源等)
- 后端系统限流(系统里配置了不能超过多少并发)、熔断、降级
什么是熔断、降级? - 熔断: 防止系统因某个服务的故障而整体崩溃。当电商平台上用户支付时,收银台发现某个支付渠道,如微信支付失败率突增,超时严重,那么就可以临时把这个支付方式熔断掉
- 降级: 主动关闭一些非核心功能,以确保核心功能的正常运行。某次腾讯视频挂了的时候,用户名称默认显示腾讯用户,这也是一种降级方式,用兜底名称做展示
3 吞吐量
吞吐量越大,性能越好;吞吐量相对稳定或者变低,可能系统达到了性能瓶颈
吞吐量变化规律: - 波动很大: 代表系统性能不稳定
- 慢慢变高,再趋于稳定: 和并发量强相关。如果并发量小于吞吐量,慢慢增大并发量,吞吐量也会随之增加
- 慢慢变低,并发量也减少了: 要么说明性能测试要结束了,并发减少;也可能是系统变的卡顿,从而导致响应时间变慢,导致单个线程发起的并发量变少
