Jmeter 对产品进行性能测试 ¶
近期,我司在项目推进中需要进行性能测试。
一、性能测试是什么 ¶
简单来说,性能测试就是 “给系统加压,测真实表现” 。通过模拟不同规模的用户访问、数据请求,主动给系统施加压力,采集响应时间、吞吐量(TPS/QPS 等)、资源占用等数据,验证系统上线后能否扛住真实业务流量,满足用户使用需求。
二、为什么要做性能测试 ¶
性能测试是系统 “健康体检” 的关键环节:
- 找瓶颈:通过加压,暴露系统短板(比如数据库查询慢、网络带宽不够、代码逻辑低效),提前发现 “看起来能用,但高并发会崩溃” 的隐患。
- 定容量:明确系统 “最多能扛多少用户、每秒能处理多少请求”,为服务器部署、资源扩容提供数据依据。
- 保体验:确保用户操作流畅(比如页面秒开、支付不卡顿),避免因系统性能差导致用户流失。
三、核心指标:QPS vs TPS ¶
这两个指标用来衡量 “系统处理请求的效率” ,但侧重点不同:
1. TPS(Transactions Per Second):事务数 / 秒 ¶
- 定义:每秒完成的 “完整业务流程” 数量。比如 “用户下单”(包含 “查询库存→创建订单→扣减库存→通知物流”),这一系列操作算 1 个事务。
- 特点:关注 “业务完整性”,反映系统处理真实用户场景的能力。如果 TPS 低,说明复杂业务流程效率差。
2. QPS(Queries Per Second):查询数 / 秒 ¶
- 定义:每秒处理的 “服务器请求” 数量。比如用户打开一个商品页,前端可能发 3 个请求(查商品信息、查评价、查推荐),这会产生 3 个 QPS。
- 特点:关注 “服务器交互次数”,更贴近技术层面的 “请求压力”。QPS 高但 TPS 低,可能是 “单次业务需要多次服务器交互”,需优化接口合并。
四、实操建议:怎么开展性能测试 ¶
以 JMeter 工具为例(LoadRunner、Gatling 逻辑类似),分 3 步:
1. 设计测试场景 ¶
- 单接口压测:比如先测 “商品查询” 接口,线程组设 100 并发,循环 10 次,看 QPS/TPS 能到多少。
- 混合场景:模拟真实用户行为(30% 浏览商品、50% 加购物车、20% 下单),用 “吞吐量控制器” 分配请求比例。
- 阶梯加压:从 100 并发逐步加到 1000,观察响应时间、吞吐量的变化拐点(比如多少并发时 TPS 开始暴跌,就是系统瓶颈点)。
2. 监控与分析 ¶
- 看响应时间:平均值、90% 分位(90% 请求的耗时)、最大值。如果 90% 分位超过 1 秒,用户体验会明显变差。
- 看资源占用:用 JVisualVM(Java 应用)或 Prometheus+Grafana 监控 CPU、内存、数据库连接池,定位 “是代码慢还是资源不够”。
- 看报错率:如果压测时错误率飙升(比如 5xx 报错),优先查接口逻辑、依赖服务(比如 Redis 宕机、数据库锁冲突)。
3. 优化与复测 ¶
- 代码层:简化冗余逻辑、加缓存(比如 Redis 存高频查询结果)、异步处理(比如短信通知放队列)。
- 数据库层:加索引、优化 SQL、分库分表(如果数据量极大)。
- 网络层:CDN 加速静态资源(图片、JS)、升级带宽、用 HTTP/2 减少请求耗时。 优化后重复压测,对比指标变化,直到满足性能要求。
不同行业不同业务可接受的响应时间是不一样的,需要根据自身情况设定合适的符合用户使用要求的响应时间。
一般情况,对于在线实时交易:
- 互联网企业:500毫秒以下,例如淘宝业务10毫秒左右。
- 金融企业:1秒以下为佳,部分复杂业务3秒以下。
- 保险企业:3秒以下为佳。
- 制造业:5秒以下为佳。
五、测试接口案例 ¶
1. 获取用户接口 ¶
测试获取用户接口案例。接口作用是获取用户信息。
GET /openapi/v1/accounts/{account_uid}/
返回结果
{
"errcode": 200,
"errmsg": "success",
"data": {
"uid": "xxx",
"status": 1,
"username": "xxx",
"phone": "xxx",
"email": "xxx",
"nickname": "xxx",
"desc": "xxx",
"role": 1,
"tier": 1,
"type": 1
}
}
1. 新建一个线程组 ¶
新建线程组 | 配置线程为 50、 启动时间设置为2s,循环次数为2次 |
---|---|
![]() |
![]() |
1. 线程数(虚拟用户数)
作用:模拟真实用户的并发量,设置的线程数 = 同时发起请求的虚拟用户数量。
示例:线程数设为 20,代表模拟 20 个用户同时访问系统。
2. Ramp-Up 时间(线程启动时长,单位:秒)
作用:控制虚拟用户的 “启动节奏”,决定所有线程完成启动的总耗时。
计算逻辑:若线程数为 20,Ramp-Up 时间设为 10 秒 → 平均每秒启动 20÷10=2 个线程(平滑递增并发,更贴近真实用户逐步涌入的场景)。
场景适配:
需 “瞬间高压”(如秒杀):Ramp-Up 设为 1 秒(线程快速全部启动);
需 “渐进加压”(如模拟用户逐步登录):拉长 Ramp-Up 时间(如 30 秒启动 100 线程)。
3. 循环次数
作用:定义每个虚拟用户发送请求的总次数。
计算逻辑:
线程数 20 + 循环次数 10 → 总请求数 = 20(线程)×10(次数)= 200 次;
勾选 “永远” → 线程会持续发送请求,直到手动停止或触发 “持续时间” 结束(常用于长时间稳定性测试,如 7×24 小时压测)。
这些参数的组合,能灵活模拟 “并发用户数、用户涌入速度、请求总量” 三个核心维度,建议结合实际业务场景
2. 新建一个HTTP请求 ¶
按照业务填写接口请求信息
![]() |
![]() |
3. 添加HTTP信息头(请求头) ¶
添加认证信息
![]() |
![]() |
4. 添加合适的响应断言 ¶
添加响应断言 | 接口成功、返回响应中包含 "errcode":200 |
---|---|
![]() |
![]() |
5. 添加监听器 ¶
JMeter 提供了多种(监听器),可直接在界面中查看测试结果,各工具功能与特点如下:
1. 明细类:查看单样本详情
-
查看结果树:以树形结构展示所有样本的响应数据,支持查看任意样本的请求与响应详情,适合调试单接口的请求逻辑或响应内容。
-
在表中查看结果:为每个样本结果生成一行记录,包含响应时间、状态等基础信息,但占用内存较多,适合小批量样本的明细查看。
2. 统计类:汇总指标分析
-
聚合报告:按请求名称生成汇总表,包含样本数、响应时间(平均值、百分位等)、吞吐量、异常率等核心指标,是压测后分析整体性能的核心工具。
-
聚合图:功能与聚合报告类似,额外支持生成条形图直观展示指标(如不同请求的平均响应时间对比),并可将图形保存为 PNG 文件,便于报告展示。
3. 趋势与摘要类:宏观监控
-
图形结果:生成简单趋势图,以曲线形式展示所有样本的响应时间变化,快速观察测试过程中性能指标的波动趋势(如随并发增加,响应时间是否飙升)。
-
生成摘要结果:可放置在测试计划任意位置,实时输出测试运行摘要(如总请求数、成功率、平均响应时间)到日志或控制台,适合监控测试整体进度。
添加结果树、汇总报告、图形结果 | 查看获取用户接口最终结构 |
---|---|
![]() |
![]() |
6. 点击运行 ¶
2. 问题查询接口 ¶
和上面过程一样
![]() |
六、 Jmeter 结果分析 ¶
1. 简单数据写入器 + HTML报告 DashBoard 演示 ¶
1. 添加简单数据写入器 ¶
![]() |
![]() |
2. 运行生成文件 ¶
点击运行生成文件 ( 500 线程、循环 30 次 ) | |
---|---|
![]() |
3. 生成 HTML 报表 ¶
点击 generate report 生成报告 | |
---|---|
![]() |
![]() |
4. 结果分析 ¶
打开 生成的 HTML 报表
上一步 output 目录中的 index.html |
---|
![]() |
核心结论:
可用性: | 请求全部 PASS (失败数 0、错误率 0% ),接口功能可用,但性能存在优化空间(响应时间指标需关注)。 |
---|---|
性能问题: | 平均响应时间 2538.04ms (约 2.5 秒),99th 分位高达 4534.93ms(近 4.5 秒),说明大量请求耗时偏长,用户体验受影响。 |
吞吐量: | 每秒处理 185.35 笔事务 ,需结合业务需求判断是否满足(如高并发场景可能需扩容)。 |
1. 可用性 ¶
可以看到请求成功的占比,本次测试中,请求全部 PASS (失败数 0、错误率 0% ),接口功能可用 |
---|
![]() |
模块拆解与指标解读:
1. APDEX(用户体验指数)
-
公式:
Apdex = (满足阈值的样本数 + 容忍阈值样本数×0.5) / 总样本数
-
参数:
-
T(容忍阈值)= 500ms
:认为 “快” 的标准(≤500ms 体验最佳); -
F(沮丧阈值)= 1.5 秒
:超过则用户明显感知卡顿(体验差); -
结果:
Apdex=0.039
(极低),说明绝大多数请求未达 “容忍标准”,用户体验差(需重点优化)。
2. Requests Summary(请求结果概览)
- 绿色饼图显示
PASS 100%
,说明接口无功能报错(网络 / 服务未返回 HTTP 错误、业务逻辑未抛异常 ),但性能问题需从响应时间分析。
3. Statistics(核心性能指标)
指标 | 解读 | 风险点 |
---|---|---|
#Samples=15000 | 共发送 15000 次请求(压测 / 实际调用量) | - |
Min=34ms / Max=6786ms | 最快 34ms 完成,最慢 6.7 秒,波动极大 | 存在 “极端慢请求”(需排查原因) |
Average=2538.04ms | 平均响应时间 2.5 秒,超过 1 秒的常规体验标准 | 整体性能需优化 |
90th/95th/99th pct | 90% 请求≤3265ms / 95%≤3451.95ms / 99%≤4534.93ms | 99th 分位接近 4.5 秒,大量请求拖慢体验 |
Throughput=185.35 TPS | 每秒处理 185 笔事务 | 若业务要求更高 TPS,需扩容优化 |
Network | 接收 / 发送流量 309.15KB/s/ 51.77KB/s,无网络带宽瓶颈(需结合服务器配置) | - |
4. Errors(错误统计)
当前无错误数据(Number of errors=0
),说明功能层面稳定,所有问题集中在 “性能慢” 而非 “功能报错”。
2. 响应时间变化 ¶
![]() |
1. 曲线与颜色含义(百分位数解释)
图表中每条颜色曲线代表不同的响应时间百分位数(Percentile),反映 “一定比例请求的耗时上限”,含义如下:
颜色 | 指标 | 解读 |
---|---|---|
紫色(Min) | 最小响应时间 | 几乎所有请求都能达到的最快速度(接近 0ms ,说明网络 / 服务本身无基础延迟)。 |
棕色(Median,50th) | 中位数(50% 分位) | 50% 的请求耗时 ≤ 此值(如 2000ms ,说明一半请求很快,一半可能较慢)。 |
绿色(95th) | 95% 分位 | 95% 的请求耗时 ≤ 此值(关键指标!代表 “大多数请求” 的性能底线)。 |
红色(99th) | 99% 分位 | 99% 的请求耗时 ≤ 此值(极端情况的底线,代表 “几乎所有请求” 的最大耗时)。 |
黄色(Max) | 最大响应时间 | 最慢请求的耗时(偶发的极端值,可能因网络抖动、资源竞争导致)。 |
2. 关键分析结论
-
整体趋势:先升后降,存在性能波动 在 12:16:38 附近(时间中点),所有百分位数的响应时间达到峰值: Max(黄色)接近 7000ms,99th(红色)接近 5000ms,说明此时系统处理请求明显变慢; 后续时间(12:16:38 后)响应时间逐步下降,恢复正常。 这种 “先升后降” 的趋势,通常与瞬时负载突增有关(如:突发流量、任务调度触发、资源临时占用 )。
-
核心问题:95th/99th 分位耗时高 95th(绿色) 和 99th(红色) 曲线明显高于 Median(棕色)和 Min(紫色),说明: 大部分请求(95%、99%)的耗时远高于 “中位数”,长尾延迟严重; 系统在这段时间内对 “高比例请求” 的响应不够稳定,可能触发了资源瓶颈(如 CPU 过载、数据库慢查询、线程池排队 )。
-
最小 / 最大响应差异大 Min(紫色)几乎为 0ms,Max(黄色)却高达 7000ms,说明: 系统处理请求的波动极大,部分请求极快(网络 / 服务无阻塞),但大量请求被延迟(需排查 “慢请求” 原因)。
3. TPS ¶
TPS 是 Transactions Per Second
的缩写,每秒处理的事务数目。
TPS 大概在 188 左右。 |
---|
![]() |
七、安装 Plugins Manager(插件管理器) ¶
1. 下载 jmeter-plugins-manager-1.3.jar文件 ¶
下载地址:https://jmeter-plugins.org/install/Install/ |
---|
![]() |
2. 移动目录 ¶
将下载下来的 jmeter-plugins-manager-1.11.jar
文件放到 jmeter
安装路径下的 \lib\ext
中。
![]() |
3. 重启服务 ¶
选项中会出现 Plugins Manager |
---|
![]() |
八、使用 PerfMon 与 ServerAgent 监控服务器资源指标 ¶
1. 安装 Permon Metrics Collector 插件 ¶
JMeter 的选项中打开 Plugins Manager ¶
![]() |
安装 PerfMon ¶
在 Available Plugins 页签搜索 “PerfMon”,勾选插件进行安装 |
---|
![]() |
2. 安装 PerfMon Server Agent插件 ¶
-
JMeterPlugins-Extras.jar
-
JMeterPlugins-Standard.jar
-
ServerAgent-2.2.3.zip
组件名称 | 类型 | 作用说明 | 部署位置 |
---|---|---|---|
JMeterPlugins-Standard.jar | 客户端插件 | 提供基础的性能测试扩展功能,包含 PerfMon 监控所需的客户端核心组件(如指标收集器、图表展示等) | JMeter 安装目录下的 apache-jmeter-5.1.1/lib/ext |
JMeterPlugins-Extras.jar | 客户端插件 | 补充标准包功能,提供更丰富的监控指标处理、数据解析义和扩展通信支持,辅助客户端与服务端交互 | 同上(与 Standard.jar 同目录) |
ServerAgent-2.2.3.zip | 服务端工具 | 包含服务器端代理程序,用于在目标服务器上收集 CPU、内存、网络等性能指标,并发送给 JMeter 客户端 | 需要监控的目标服务器(解压后直接运行) |
- 客户端插件(
Standard.jar
和Extras.jar
)需安装在运行 JMeter 的机器上,用于解析和展示服务端传来的监控数据。 - 服务端工具(
ServerAgent
)需部署在被监控的服务器上,通过默认端口(4444)与 JMeter 客户端通信,主动推送性能指标。 - 三者配合使用才能完成完整的服务器性能监控流程:
ServerAgent
采集数据 → 客户端插件接收并处理 → 在 JMeter 中展示监控结果。
JMeterPlugins-Extras 、JMeterPlugins-Standard 的下载地址:https://jmeter-plugins.org/downloads/old/ |
---|
![]() |
客户端( Jmeter 端) ¶
移动目录 ¶
插件压缩包名称 | 需提取的文件名称 | 目标存放路径 | 说明 |
---|---|---|---|
JMeterPlugins-Standard-1.4.0.zip | JmeterPlugins-Standard.jar | apache-jmeter-5.1.1\lib\ext | 标准插件库文件 |
JMeterPlugins-Extras-1.4.0.zip | JMeterPlugins-Extras.jar | apache-jmeter-5.1.1\lib\ext | 扩展插件库文件 |
操作提示:
- 分别解压两个压缩包
- 从各自的
lib\ext
目录中找到对应 JAR 文件 - 复制到 JMeter 安装目录的
apache-jmeter-5.1.1\lib\ext
文件夹中 - 重启 JMeter 使插件生效
![]() |
服务端(Linux) ¶
下载 ServerAgent-2.2.3.zip ¶
下载地址:https://github.com/undera/perfmon-agent/releases |
---|
![]() |
linux 中启动服务 ¶
bash startAgent.sh --udp-port 0 --tcp-port 333
已安装配置好 Java 环境、linux 服务器监听端口为 333 |
---|
![]() |
3. jmeter客户端监听测试 ¶
添加监听器并配置监控的数据 ¶
添加 → 监听器 → jp@gc - PerfMon Metrics Collector | 配置需要监控的数据。选择要监控的指标:CPU、Memory、Disks I/O、Network I/O, |
---|---|
![]() |
![]() |
查看测试结果对应的性能指标 ¶
设置 线程100、循环两次 点击启动 | 查看服务器相关指标 |
---|---|
![]() |
![]() |
解决中文返回乱码 ¶
修改 jmeter 配置文件,并重启。 |
---|
![]() |
九、优化流程 ¶
1. 使用 csv data set config ¶
第一个分词接口是输入问题、然后返回分词后的结果。目前是压测单个问题的场景、现在新增需要压测多个问题的场景。
添加 csv data set config 资源 | 添加文件地址、变量、与文件内容 |
---|---|
![]() |
![]() |
修改 http 请求、使用 ${question} | 点击运行、查看结果发现请求是多问题 |
---|---|
![]() |
![]() |
2. 使用 json提取器(动态提取变量) ¶
因为我们输入多个问题、返回的结果也是不同的结果、而后面的生成 sql 接口需要依赖输入问题后分词的结果。所以我们使用 json 提取器。
先却换到 JSON Path Tester 提取参数 | 我的结构使用 $.data.tokens[*].word 成功提取到分词结果 |
---|---|
![]() |
![]() |
创建 JSON 提取器 | 使用上一步使用成功的参数配置、 |
---|---|
![]() |
![]() |
3. 使用 JSR223 后置处理器(生成数组) ¶
添加 JSR223 后置处理器 | 配置 JSR223 后置处理器 |
---|---|
![]() |
![]() |
添加 Debug PostProcessor 来查看是否成功 | 查看成功获取到分词结果。。。。。。。。。。。。 |
---|---|
![]() |
![]() |
4. 使用 JSR223 后置处理之后的流程 ¶
已经使用 json 提取器和 JSR223 后置处理器动态的提取出了变量。接下来使用
http 请求使用生成的动态数组 |
---|
![]() |
查看发现 1-分词接口 使用了 csv 中不同的请求问题。 | |
---|---|
![]() |
查看发现 2-生成sql接口 使用了 1-分词接口 不同的请求问题返回的分词结果 |
---|
![]() |