Windows 安装 使用JMeter 教程

Windows 安装 使用JMeter 教程(只用来熟悉界面、写脚本调试,不涉及 Gitea/Jenkins)

    • [Apache JMeter 简介](#Apache JMeter 简介)
    • JMeter安装
    • JMeter基础使用
      • [1. JMeter核心组件(测试计划组成)](#1. JMeter核心组件(测试计划组成))
      • [2. 设置中文语言](#2. 设置中文语言)
      • [3. 搭建一个 JMeter 脚本,**模拟 5 个用户,2 秒内陆续上线,一共循环 3 轮,并发访问虚拟机里 Node 服务首页接口 `http://192.168.88.132:3001/\`\*\*](#3. 搭建一个 JMeter 脚本,模拟 5 个用户,2 秒内陆续上线,一共循环 3 轮,并发访问虚拟机里 Node 服务首页接口 http://192.168.88.132:3001/)
      • [4. 添加【响应断言】](#4. 添加【响应断言】)
      • [5. 接口关联(JSON 提取器,Token 传递)](#5. 接口关联(JSON 提取器,Token 传递))
      • [6. CSV 数据集参数化(多个用户,不同账号密码)](#6. CSV 数据集参数化(多个用户,不同账号密码))
      • [7. 非 GUI 模式运行 + 生成 HTML 仪表盘](#7. 非 GUI 模式运行 + 生成 HTML 仪表盘)

Apache JMeter 简介

Meter 是 Apache 基金会 开发维护、纯 Java 编写的开源免费性能 / 负载测试工具,最初专门用来做 Web 应用压力测试,现在支持几乎主流协议,是软件测试、性能测试岗位最常用工具之一。
核心原理:用线程 (Thread)模拟真实用户,并发向服务器发送请求;采集响应时间、吞吐量、错误率等指标,评估系统在多用户访问下的性能、稳定性,找到系统瓶颈
特点:

1. 跨平台 :Java 程序,Windows / Linux / Mac 都能跑;GUI 界面写脚本,正式压测推荐 CLI 非 GUI 模式 (节省资源,压测更稳定)

2. 多协议支持 :HTTP/HTTPS(最常用,接口、网站)、REST/SOAP 接口、JDBC 数据库、FTP、TCP、JMS 消息、SMTP 邮件等Apache JMe...

3. 多种测试类型:

  • 负载测试:模拟正常并发,看系统性能
  • 压力测试:不断加大并发,找到系统崩溃临界点
  • 并发测试、稳定性测试(长时间压测)、基准测试、简单接口功能测试

4. 高可扩展 :插件生态丰富(比如 JMeter Plugins);支持分布式压测(多台机器一起发压力)

5. 结果可视化:内置聚合报告、查看结果树;压测完成自动生成 HTML 性能报告,方便输出测试报告.

JMeter安装

  1. 安装jdk 11教程 (兼容性最好,JMeter5.4 + 都支持)
  2. 下载 JMeter
    官网:https://archive.apache.org/dist/jmeter/binaries/
    选版本:apache-jmeter-5.6.3.zip(稳定版)

下载 zip 压缩包,不用安装,解压即用。

  1. 解压(路径不能中文、空格)
  1. 启动 JMeter 图形界面
    进入文件夹:D:\tools\apache-jmeter-5.6.3\bin
    找到文件:jmeter.bat

    双击运行,会弹出一个黑色 cmd 窗口,然后 JMeter GUI 主界面就出来了。

常见问题:双击 jmeter.bat 黑窗口一闪而过

原因:Java 没装好 / JAVA_HOME 环境变量错误。

排查:打开 cmd,手动 cd 到 bin 目录,执行 jmeter.bat,可以看到报错信息

JMeter基础使用

1. JMeter核心组件(测试计划组成)

  • 测试计划 (Test Plan) :是整个 JMeter 脚本的根容器,保存所有线程组、请求、监听器。后缀 .jmx,本质是 xml 文件,压测脚本。
  • 线程组 (Thread Group):模拟用户;线程数 = 并发用户数,设置启动时间、循环次数、压测时长
  • 取样器 (Sampler):发送请求(HTTP 请求、JDBC 请求等,真正干活发起调用)
  • 配置元件:全局变量、请求头、Cookie、CSV 参数化数据
  • 前置 / 后置处理器:请求前准备数据、请求后提取返回值(正则、JSON 提取器)
  • 断言 (Assertion):校验响应结果是否符合预期,判断请求成功 / 失败
  • 监听器 (Listener):收集、查看测试数据(聚合报告最核心)
  • 定时器:模拟用户思考时间,控制请求间隔

2. 设置中文语言

临时切换 :

Options → Choose Language → Chinese (Simplified)

永久切换:

  1. 关闭当前 JMeter 软件
  2. 进入你的 jmeter 目录下的 bin 文件夹
    示例路径:D:\tools\apache-jmeter-5.6.3\bin
  3. 找到文件:jmeter.properties,用记事本 / Notepad++ 打开
  4. 按 Ctrl+F 搜索关键词:language
    找到这一行:#language=en
  • 把前面的#删掉(# 代表注释,删掉才会生效)
  • en 改成 zh_CN
    修改后变成:
    language=zh_CN
  1. Ctrl+S保存文件
  2. 重新双击 jmeter.bat 启动 JMeter,打开直接就是中文界面!
    ⚠️ 注意:zh_CN 大小写不能写错,下划线不能丢

3. 搭建一个 JMeter 脚本,模拟 5 个用户,2 秒内陆续上线,一共循环 3 轮,并发访问虚拟机里 Node 服务首页接口 http://192.168.88.132:3001/

【注意】:虚拟机里 Node 服务首页接口 `http://192.168.88.132:3001/,这个接口是上两篇分享里搭建好了的。

流程:创建测试计划 → 创建 5 用户线程组(2 秒拉起,循环 3 次)→ 写 HTTP 取样器访问虚拟机 Node 首页 → 添加查看结果树用于调试,运行脚本看请求是否通,最后保存脚本。

  1. 打开 JMeter,自带一个【测试计划】,改名字:Node首页压测练习
  2. 右键【测试计划】→ 添加 → Threads (Users) → 线程组
    • 线程数:5(模拟 5 个用户)
    • Ramp-Up 时间:2(2 秒内拉起 5 个用户)
    • 循环次数:3
  3. 添加 HTTP 请求默认值:
    左侧树右键 线程组 → 添加 → 配置元件 → HTTP 请求默认值
    在右侧填写:
  • 协议 :http
    服务器名称或 IP :192.168.88.132
  • 端口号 :3001

这样下面的 HTTP 取样器就不用重复写 IP 和端口了。

  1. 右键【线程组】→ 添加 → 取样器 → HTTP 请求

    • 名称:访问首页
    • 协议:http
    • 服务器名称或 IP:192.168.88.132(你的虚拟机 Node 服务 IP)
    • 端口号:3001
    • 请求方式: GET
    • 路径:/

  2. 添加查看结果树(调试用)

右键 线程组 → 添加 → 监听器 → 查看结果树

这个组件用来调试脚本 :

>- 运行后点击某一条请求,可以看到请求参数和服务器返回内容

>- 确认返回状态码是 200,页面内容正常

⚠️ 正式压测时建议禁用 它,因为逐条记录会消耗 JMeter 自身性能,影响压测结果。

  1. 添加聚合报告(看压测指标)
列名 含义
样本数 总请求数,应该是 15
平均值 平均响应时间(毫秒)
中位数 / 90%/95%/99% 分位数响应时间,90% 的请求快于多少毫秒
吞吐量 每秒处理请求数(TPS)
错误率 失败请求占比,理想是 0%
  1. 运行测试

点击顶部工具栏的 绿色启动按钮 ▶

第一次运行会弹出「保存测试计划」提示,选个位置保存 .jmx 文件

运行过程中可以去【查看结果树】看实时请求情况

取样器结果:

响应数据:

跑完后打开【聚合报告】查看结果

4. 添加【响应断言】

  1. 右键取样器 访问Node首页 → 添加 → 断言 → 响应断言
  2. 右侧配置:
  • 名称:首页_响应断言
  • 应用于:主样本和子样本
  • 测试字段:响应文本
  • 模式匹配规则:包含
  • 测试模式 :填写你首页 HTML 里的关键字,例如 Hello CI/CD

    可以先在【查看结果树】的【响应数据】里复制页面里存在的文字。
  1. 保存脚本,运行测试

成功:全部绿色; 如果页面没有Hello CI/CD,请求直接标红报错。

原理:JMeter 收到响应后,检查返回文本是否包含 Welcome,不包含就判定请求失败。

成功:

失败:

将【测试字段】修改为welcome,不存在的文本

断言中没有找到【welcome】字段

5. 接口关联(JSON 提取器,Token 传递)

业务场景:Node 服务有登录接口 POST /api/login,登录成功返回 {"code":200,"token":"abc123xyz"}

将gitea服务器项目中的app.js文件内容中,添加接口

内容如下:

bash 复制代码
const express = require('express');
const app = express();
const port = 3000;
// 版本号,后续改这里即可
const version = "v1.2.1";

// ✅ 重点:解析POST的JSON请求体,放在所有路由前面!
app.use(express.json());

app.get('/', (req, res) => {
  // 返回HTML页面
  res.send(`
 <!DOCTYPE html>
 <html lang="zh-CN">
 <head>
     <meta charset="UTF-8">
     <title>CI/CD 演示页面</title>
     <style>
         * {
             margin: 0;
             padding: 0;
             box-sizing: border-box;
             font-family: "Microsoft Yahei", sans-serif;
         }
         body {
             background-color: #f0f4f8;
             display: flex;
             align-items: center;
             justify-content: center;
             height: 100vh;
         }
         .card {
             background: #ffffff;
             padding: 40px 60px;
             border-radius: 16px;
             box-shadow: 0 8px 24px rgba(0,0,0,0.1);
             text-align: center;
         }
         .title {
             font-size: 32px;
             color: #2c3e50;
             margin-bottom: 16px;
         }
         .version {
             font-size: 20px;
             color: #3498db;
             font-weight: bold;
         }
         .tip {
             margin-top: 24px;
             font-size:14px;
             color:#7f8c8d;
         }
     </style>
 </head>
 <body>
     <div class="card">
         <div class="title">Hello CI/CD!</div>
         <div class="version">当前版本:${version}</div>
         <div class="tip">✅ Jenkins + Gitea 自动发布流水线测试成功</div>
     </div>
 </body>
 </html>
  `);
});

app.post('/api/login',(req,res)=>{
  console.log("收到登录请求,body:", req.body)
  const {username,password} = req.body
  if(username === 'test01' && password === '123456'){
    // =====这里token复制完整字符串,不要少字符!=====
    const myToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
    res.json({
      code:200,
      msg:"success",
      data:{
        accessToken: myToken
      }
    })
  }else{
    res.json({code:400,msg:"账号密码错误"})
  }
})

app.get('/api/home',(req,res)=>{
  const auth = req.headers.authorization
  console.log("收到的auth头:", auth)
  if(!auth){
    return res.json({code:401,msg:"无权限,请传入token"})
  }
  const token = auth.split(' ')[1]
  const myToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
  if(token === myToken){
    res.json({
      code:200,
      msg:"访问首页业务接口成功",
      data:{version:version}
    })
  }else{
    res.json({code:401,msg:"token无效"})
  }
})


app.listen(port, '0.0.0.0', () => {
  console.log(`服务启动成功,监听端口 ${port}`);
});
  1. 新建【登录接口】HTTP取样器
    右键【线程组】→ 添加 → 取样器 → HTTP 请求
  • 名称:登录接口-POST获取token

因为配置了【HTTP 请求默认值】,服务器名称、端口留空不用填

  • 请求方法:POST
  • 路径:/api/login
  • 消息体数据(勾选【消息体数据】,粘贴下面 JSON)
bash 复制代码
{
    "username":"user01",
    "password":"123456"
}

重点:POST 提交 JSON,必须添加【HTTP 信息头管理器】

2. 添加【HTTP 信息头管理器】

右键 登录接口-POST获取token → 添加 → 配置元件 → HTTP 信息头管理器

点【添加】,新增一行:名称: Content-Type ; 值:application/json

原理:后端需要识别请求体是 JSON 格式,如果缺少这个头,后端接收参数失败,登录直接报错!

这个信息头管理器属于登录接口的子元件,只作用于当前登录取样器。

  1. 添加【JSON提取器】后置处理器
    后置处理器:在当前 HTTP 请求执行完成、拿到响应之后,才会执行 ,所以必须放在登录接口下面,作为子元件
    右键 登录接口-POST获token → 添加 → 后置处理器 → JSON 提取器
    参数解说:
参数 填写内容 详细解释
引用名称 token 定义变量名,后面使用:${token}
JSON 路径表达式 $.token $代表 JSON 根节点; .token代表取根下 token 字段返回示例{"code":200,"token":"abc123xyz"}, $.token就取出abc123xyz
匹配数字 1 多个匹配结果时取第 1 个;固定写 1 即可
缺省值 NOT_FOUND 提取失败时,变量默认值是 NOT_FOUND,方便排查
  1. 添加调试取样器
    右键线程组 → 添加 → 取样器 → 调试取样器
    运行脚本,查看结果树打开调试取样器,可以直接看到 ${token} 的值,快速判断提取是否成功。

正式压测前,禁用调试取样器,不然会增加额外请求。

  1. 新建鉴权接口(需要携带Token访问的接口)
    右键【线程组】→ 添加 → 取样器 → HTTP 请求
  • 名称:鉴权接口-首页信息
  • 请求方法:GET
  • 路径:/api/home

  1. 给鉴权接口添加请求头Authorization

    右键 鉴权接口-首页信息 → 添加 → 配置元件 → HTTP 信息头管理器

    新增一行:名称:Authorization; 值:Bearer ${token}

    解析:

    ${token}:JMeter 变量语法,运行的时候自动替换成 JSON 提取器拿到的值,例如 Bearer abc123xyz

    Bearer 后面必须带一个空格 !很多人踩坑:写成Bearer${token},后端直接报 token 无效!

  2. 运行脚本,结果排查

    点击顶部绿色运行按钮,打开【查看结果树】

    执行顺序说明:

    <1>. 先执行登录接口,发送账号密码

    <2>. 收到后端返回 JSON,JSON 提取器立刻执行 ,读取 token 保存到变量 ${token}

    <3>. 再执行鉴权接口,执行前读取 HTTP 信息头管理器,自动替换 ${token},带上 Authorization 请求头访问接口

6. CSV 数据集参数化(多个用户,不同账号密码)

场景:5 个虚拟用户,每个用户使用独立账号,不要全部用 user01。

在JMeter下的bin文件 D:\JMeter\apache-jmeter-5.6.3\bin ,新建 userlist.csv

用 Notepad++ 打开写入下面内容(不要加表头,一行一组账号密码)

bash 复制代码
test01,123456
test02,123456
test03,123456
test04,123456
test05,123456

编码选 UTF-8

  1. 右键线程组 → 添加 → 配置元件 → CSV 数据文件设置
    配置:
  • 文件名:D:\JMeter\apache-jmeter-5.6.3\bin\userlist.csv
  • 变量名称:username,password
  • 分隔符:,
  • 回收周期:循环读取
  • 遇到文件结束符:停止线程


    将该配置放到【登录接口】前面
  1. 修改登录接口的 JSON 消息体,使用变量替换:
bash 复制代码
{
  "username":"${username}",
  "password":"${password}"
}
  1. 设置【线程数:5】:5个账号,设置5个线程,【循环次数: 1】:循环一次即可
  1. 点击【启动】按钮,进行测试并查看【结果树】

    账号和密码登录成功:

    除了第一条的账号正常,另四个账号不存在

7. 非 GUI 模式运行 + 生成 HTML 仪表盘

GUI 界面只用来调试脚本,正式压测禁止 GUI 运行,GUI 会占用大量资源,结果不准。

  1. 打开 CMD 命令提示符,cd 进入 jmeter 的 bin 目录
bash 复制代码
cd D:\JMeter\apache-jmeter-5.6.3\bin
  1. 执行下面这条命令
bash 复制代码
jmeter.bat -n -t 线程组.jmx -l result.jtl -e -o report_html

参数解释:

  • -n:非 GUI 模式
  • -t 线程组.jmx:你的脚本文件名
  • -l result.jtl:保存压测结果文件
  • -e:测试结束后生成 html 报告
  • -o report_html:报告输出文件夹,每次运行前这个文件夹必须是空的!

每次执行前,把 report_html 文件夹里面的文件全部删除,否则报错。

执行完成后,打开文件夹 report_html,双击 index.html

✅ 仪表盘包含:响应时间趋势图、TPS 曲线、错误统计、服务器性能指标、请求分布,比聚合报告强大很多。

相关推荐
报错小能手4 小时前
Channel面试题。Sync面试题
linux·服务器·windows
闭着眼刷牙4 小时前
pc接入rndis等网卡设备后卡死几分钟,已解决
windows
Madison-No77 小时前
多语言聊天大模型--测试报告
linux·git·python·selenium·jmeter·自动化·postman
Patrick在香港10 小时前
同一份脚本,mac 正常 Windows 乱码:open() 默认编码实测(附 3.15 终局)
utf-8·windows·python·macos·跨平台·编码·标准库
冷凝娇10 小时前
【学习jmeter】ServeRest
jmeter
zuozewei13 小时前
第00篇-为什么是-k6-AI-时代的工具选型
软件测试·jmeter·性能测试·ai测试·k6
郭庆汝13 小时前
windows本地部署AgentDesk
windows
笨笨D幸福13 小时前
win11 vhdx/wtg 安装出现问题,提示 Windows 安装程序无法将 Windows 配置为在此计算机的硬件上运行
windows
h397421 小时前
DirectShow过滤器开发-视频源过滤器
c++·windows·音视频·directshow