第3章 压测工具入门:JMeter基础使用
做性能测试这么多年,我见过不少团队拿着JMeter却只会点“开始”和“停止”。说实话,这工具远比你想象的强大。今天咱们就从最基础的部分开始,把JMeter的底子打扎实。
3.1 JMeter是什么?为什么选它?
JMeter是Apache基金会下的开源压测工具。它最初是为Web应用设计的,后来扩展到了数据库、FTP、消息队列等各种协议。我个人习惯用它做HTTP接口的吞吐测试,因为它的插件生态实在太丰富了。
你可能会问:“市面上压测工具那么多,为什么偏要学JMeter?”
三个理由:
- 免费开源 —— 没有授权费用,团队随便用
- 跨平台 —— Windows、Linux、macOS都能跑
- 扩展性强 —— 官方插件+第三方插件,几乎什么协议都能测
3.2 安装与启动
JMeter依赖Java环境。先确认你的机器上有JDK 8或更高版本:
java -version
然后去Apache官网下载JMeter的二进制包。解压后,进入bin目录:
- Windows:双击
jmeter.bat - Linux/Mac:运行
sh jmeter.sh
启动后你会看到一个空白的测试计划界面。嗯,这就是我们接下来要操作的主战场。
jmeter.bat 或 jmeter.sh 里的 HEAP 参数。我曾经在压测一个高并发项目时,默认的512MB堆内存直接OOM,后来改成了 -Xms2g -Xmx4g 才稳住。
3.3 创建线程组 —— 模拟用户行为
线程组是JMeter里最核心的概念。说白了,它就是用来定义“有多少个虚拟用户”以及“这些用户怎么跑”的。
右键点击“测试计划” → 添加 → 线程(用户) → 线程组。你会看到这样的配置面板:
| 参数 | 说明 | 我的常用值 |
|---|---|---|
| 线程数 | 虚拟用户的数量 | 先设10,逐步增加到100、500 |
| Ramp-Up时间(秒) | 所有线程启动完毕需要的时间 | 线程数 × 0.1,比如100线程就设10秒 |
| 循环次数 | 每个线程执行多少次请求 | 勾选“永远”,配合调度器控制时长 |
| 调度器 | 设定测试的持续时间 | 压测一般跑5~10分钟 |
举个例子:我要模拟100个用户,在10秒内全部启动,然后持续压测5分钟。配置就是:线程数=100,Ramp-Up=10,循环次数勾选“永远”,调度器里填持续时间=300秒。
3.4 配置取样器 —— 定义要压测的请求
线程组只是定义了“谁在跑”,取样器才是定义“跑什么”。
右键点击线程组 → 添加 → 取样器 → HTTP请求。配置项如下:
- 协议: http 或 https
- 服务器名称或IP: 目标地址,比如 api.example.com
- 端口号: 默认80(http)或443(https)
- 方法: GET、POST、PUT、DELETE等
- 路径: 接口路径,比如 /api/v1/users
- 参数: 可以添加请求参数或Body数据
举个例子,我要压测一个登录接口:
协议:https
服务器:api.example.com
端口:443
方法:POST
路径:/api/v1/login
Body:{"username":"test","password":"123456"}
这里有个小技巧:如果接口需要Token或Session,可以添加一个“HTTP信息头管理器”,在里面设置 Authorization: Bearer xxx。我在项目中经常用这种方式模拟已登录用户的请求。
3.5 添加监听器 —— 看结果
没有监听器,压测就是盲打。JMeter提供了多种监听器,我常用的就三个:
- 查看结果树: 调试用,能看到每个请求的请求头和响应体
- 聚合报告: 核心报表,包含吞吐量、平均响应时间、错误率等
- 图形结果: 可视化趋势,适合观察性能变化
右键点击线程组 → 添加 → 监听器 → 聚合报告。跑完压测后,你会看到类似这样的数据:
| 指标 | 含义 | 健康值参考 |
|---|---|---|
| #样本 | 总请求数 | 越多越好 |
| 平均值 | 平均响应时间(ms) | < 500ms |
| 中位数 | 50%的请求在这个时间内完成 | < 500ms |
| 90%百分位 | 90%的请求在这个时间内完成 | < 1000ms |
| 最小值 | 最快响应时间 | 越低越好 |
| 最大值 | 最慢响应时间 | 警惕异常值 |
| 吞吐量 | 每秒处理的请求数(TPS) | 越高越好 |
| 错误率 | 失败请求占比 | < 1% |
3.6 聚合报告解读 —— 看懂数据背后的故事
聚合报告是JMeter里最重要的报表。但很多人只会看“平均值”,这其实是个陷阱。
举个例子:
#样本:10000
平均值:500ms
中位数:200ms
90%百分位:1500ms
99%百分位:5000ms
吞吐量:200 TPS
错误率:2%
平均值500ms看起来还行,但90%百分位是1500ms,99%百分位是5000ms。这说明什么?说明大部分请求很快(中位数200ms),但有一小部分请求慢得离谱。这种“长尾延迟”在性能优化中非常常见。
我一般这样解读:
- 平均值 + 中位数: 如果两者接近,说明性能稳定;如果平均值远大于中位数,说明存在慢请求拖后腿
- 90%/99%百分位: 关注尾部延迟,这是用户体验的关键
- 吞吐量: 结合线程数看,如果线程数增加但吞吐量不涨,说明系统已经达到瓶颈
- 错误率: 超过1%就要排查原因,可能是超时、服务器拒绝连接、参数错误等
3.7 一个完整的压测流程
说了这么多,咱们来走一遍完整的流程。假设我要压测一个用户列表接口:
- 启动JMeter,创建测试计划
- 添加线程组:线程数=50,Ramp-Up=5秒,循环次数=永远,持续时间=300秒
- 添加HTTP请求默认值:协议=http,服务器=localhost,端口=8080
- 添加HTTP请求:路径=/api/users,方法=GET
- 添加HTTP信息头管理器:Content-Type=application/json
- 添加聚合报告和图形结果
- 点击绿色“启动”按钮
- 观察图形结果,等待测试结束
- 查看聚合报告,记录关键指标
就这么简单。但实际项目中,你还需要考虑参数化(用CSV文件传入不同用户数据)、断言(验证响应是否正确)、定时器(模拟用户思考时间)等高级功能。这些我们后面章节会详细讲。
3.8 JMeter核心组件关系图
下面这张图展示了JMeter各组件之间的协作关系。我建议你把它保存下来,每次搭建压测脚本时对照着看:
3.9 常见问题与避坑
最后分享几个我在项目中踩过的坑:
- 监听器不要放在线程组外面: 否则只能看到汇总数据,看不到每个线程组的独立表现
- 压测时关掉“查看结果树”: 它会记录每个请求的完整数据,非常耗内存。我一般只在调试时打开,正式压测时关掉
- 分布式压测时注意时间同步: 如果多台机器时间不一致,聚合报告里的时间戳会乱掉。我曾经因为这个排查了整整一天
- CSV参数化文件路径用绝对路径: 相对路径在分布式压测时容易找不到文件
好了,JMeter的基础使用就讲到这里。你可以在本地搭一个简单的Web服务,然后按照上面的步骤跑一遍。只有亲手操作过,这些概念才能真正变成你自己的东西。