JMeter 脚本录制这件事,很多新手第一步就卡住了。明明按照网上的教程一步一步走,浏览器怎么也打不开页面,或者打开之后 JMeter 里一个请求都没有,再要么全是红色报错。我早期刚接触 JMeter 的时候,也在这上面折腾了好几天,后来把所有环节拆开一个个排查,才发现绝大多数问题都出在环境配置、证书安装和浏览器代理设置这三件事上。这篇文章就把我自己录制的完整流程和踩过的坑都写出来,帮你快速跑通 JMeter 脚本录制这条路。
1. 录制前必须搞清楚的三件事
1.1 脚本录制的本质是什么
很多初学者会把 JMeter 脚本录制想得很神秘,其实它的本质非常简单:JMeter 在你电脑上启动一个代理服务器,然后你让浏览器把所有请求都走这个代理,JMeter 作为中间人把请求“看”一遍并记录下来,最后整理成测试脚本。
这个原理和抓包工具是一样的。你平时用 Charles、Fiddler 抓 App 的请求,抓到的就是 HTTP/HTTPS 报文。JMeter 干的是同样的事,只不过它把抓到的请求直接转换成了自己的线程组采样器结构,省去了手工抄写接口参数的时间。
理解了这一点,后面的操作就有方向了。录制只是手段,最终目的是拿到一份可以被压测或功能验证的脚本。所以录制完了不是结束,还要对脚本做过滤、参数化、断言等一系列处理,这块我在第 4 节会详细讲。
1.2 不同录制方案的优缺点对比
JMeter 官方对脚本录制提供的标准方案是 HTTP 代理服务器,但实际工作中我见过不少人用别的方式,我也尝试过各种方案,这里把它们的优劣列出来,方便你按自己的场景选。
| 录制方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| HTTP 代理服务器 | 官方原生支持,无需额外安装软件,可录制 HTTPS 请求 | 配置步骤多,需要处理证书,需要设置浏览器代理 | 最通用,推荐新手掌握 |
| Badboy / Selenium 等工具录制 | 可视化操作录制,能生成部分 JMeter 脚本 | 已停止维护或兼容性差,生成的脚本结构混乱 | 老教程常用,现在不建议 |
| 手工编写脚本 | 脚本结构清晰,参数可控,没有录制垃圾请求 | 需要完整掌握接口文档,编写效率低 | 接口文档完善的场景 |
| 抓包工具转脚本 | 可以用 Charles 等工具抓包后手工转成 JMeter 请求 | 转换工作量大,不如直接用代理录制方便 | 移动端抓包辅助分析时 |
我个人的建议是:新手第一遍老老实实走 HTTP 代理服务器方案。这个方案虽然步骤多,但每一步都是 JMeter 常用的基础操作,你把这些操作练熟了,后面遇到问题才会知道病灶在哪里。
1.3 环境准备:JDK 与 JMeter 安装
在开始录制之前,先把环境装好。JMeter 是纯 Java 应用,所以第一步是装 JDK。很多新手一上来就装 JMeter,结果双击启动脚本没反应,十有八九是 JDK 没装或者版本不匹配。
JDK 版本选择上,JMeter 5.x 系列要求 JDK 8 及以上,JMeter 5.5 之后建议 JDK 8 或 JDK 11,最新的 JMeter 5.6 则要求 JDK 8 以上且推荐 11 或 17。保守起见,装 JDK 11 是比较稳的选择,兼容性最好。装完 JDK 后在命令行输入java -version,能看到版本号就说明环境没问题。
接着去 Apache JMeter 官网下载压缩包,Windows 选择 zip 包,Linux 和 Mac 选择 tgz 包。下载后直接解压即可,不需要安装。进入bin目录,Windows 下双击jmeter.bat启动,Mac/Linux 下运行sh jmeter启动。启动后如果界面字体太小,可以在jmeter.bat或jmeter启动脚本里调整JVM_ARGS,或者直接在 Options 菜单里改外观和字号。
2. 录制前的基础配置细节
2.1 线程组与测试计划的创建规范
录制前先理清测试计划的结构,不要一上来就随便录。我是习惯先在测试计划上把用途写清楚,再创建线程组。右键测试计划,选择“添加 - 线程(用户) - 线程组”,线程组里有几个关键参数,录制阶段不用管得太细,但可以顺手设置一个合理值。
线程数代表模拟多少个用户,Ramp-Up 时间代表多少秒内启动完这些用户,循环次数代表每个用户跑几遍。录制阶段填线程数 1、Ramp-Up 1、循环次数 1 就够了,毕竟只是录脚本,不是压测。等你脚本整理好了,再回去调这些参数做真正的压力测试。
另外提醒一下,测试计划里有一个“独立运行每个线程组”的选项,如果你一个计划里建了多个线程组,比如登录线程组、业务线程组、清理线程组,建议勾选这个选项,让它们按顺序执行。录制阶段虽然用不上,但提前养成好习惯可以少踩后面的坑。
2.2 HTTP 代理服务器的参数选择技巧
这是录制最核心的一步。右键线程组,选择“添加 - 非测试元件 - HTTP 代理服务器”,打开之后你会看到几个关键配置项。
全局设置里,端口号默认是 8888,这个端口就是 JMeter 代理监听的端口,你等会儿要在浏览器里填的代理端口就是它。如果你的 8888 端口被其他程序占了,可以改成 8889 之类的,但要注意改完之后浏览器那边也要跟着改。目标控制器选择你刚才创建的线程组,这样录制的请求才会归到线程组下面,不然会堆在测试计划根节点上,整理起来非常麻烦。
请求筛选部分,我强烈建议在录制前就配置好“排除模式”,把图片、CSS、JS、字体这类静态资源排除掉。常见的小尾巴包括.*\.js、.*\.css、.*\.png、.*\.jpg、.*\.ico、.*\.gif。这样录出来的脚本干净很多,不用录制完再去手动删一大堆无用的请求。
HTTPS 抓包的地方,有一个“HTTPS 安全证书”区域,里面能设置证书有效期天数,默认 7 天。录制 HTTPS 脚本必须让 JMeter 生成一个 CA 证书,然后导入到浏览器或系统里。录制开始前先点一下下面的“生成根 CA 证书”按钮,JMeter 会在用户主目录的apache-jmeter/bin或库目录里生成一个ApacheJMeterTemporaryRootCA.crt文件,待会儿要用。
提示:代理服务器录制完成后,记得点击“停止”按钮,不然代理会一直占用端口,后面其他工具想用这个端口会报占用错误。
2.3 HTTPS 证书安装的关键细节
HTTPS 脚本录制绕不开证书这一步,这也是新手最头疼的地方。HTTP 代理录制 HTTP 请求时不需要证书,但一旦录制 HTTPS 页面,浏览器会提示“您的连接不是私密连接”或者“代理服务器证书无效”,这就是因为浏览器不信任 JMeter 生成的这个临时 CA 证书。
解决办法取决于你用的是什么浏览器。Chrome 和 Edge 都是调用系统证书库,所以要把证书导入到操作系统里。以 Windows 为例:双击那个.crt文件,选择“安装证书”,存储位置选“本地计算机”,然后选择“将所有证书都放入下列存储”,点击“浏览”,选择“受信任的根证书颁发机构”,一路下一步完成导入。
Firefox 比较特殊,它自己维护一套证书库,不走系统证书。即使你导入到 Windows 系统里,Firefox 依然会报错。要么你干脆不用 Firefox 录制,要么就在 Firefox 的设置里搜索“证书”,打开“查看证书”面板,在“证书颁发机构”标签页里导入 JMeter 生成的证书,并勾选“信任由此证书颁发机构来标识网站”。
证书导入成功后,浏览器地址栏仍然可能出现锁上带感叹号的标志,这是正常的,因为是自签名证书。只要你没有收到代理错误提示,说明代理连通了,可以正常开始录制。
3. 录制实操全流程
3.1 浏览器代理设置的标准姿势
证书处理完了,下一步是让浏览器把请求转给 JMeter 代理。这里很多人会用错方法,我直接说标准操作。
在 Chrome 地址栏输入chrome://settings,搜索“代理”,打开“打开您计算机的代理设置”。在“手动设置代理”区域,把“使用代理服务器”开关打开,地址填127.0.0.1,端口填8888,也就是你在 JMeter HTTP 代理服务器里配置的那个端口。设置好之后点保存。
这里有个容易忽略的细节:代理设置完成之后,不要急着点 JMeter 的“启动”按钮。我建议先确认一下 JMeter 代理有没有启动,再操作浏览器打开目标网站。不然代理开着但 JMeter 没启动,浏览器会一直转圈打不开页面,新手还以为是自己网络断了,折腾半天才发现是顺序错了。
正确的录制顺序是:先在 JMeter 里启动 HTTP 代理服务器,看到日志区域打印出“Proxy up and running at port 8888”之类的信息,再操作浏览器访问目标站点。这样请求一产生就能被 JMeter 捕获到。
3.2 录制过程中的操作节奏控制
录制开始后,你要像正常用户一样操作被测系统。但这里有一个节奏问题,很多人录完发现请求乱成一团,或者数据不对,就是因为录制时操作太快、路径太乱。
建议录制前先列一下操作路径。比如你要录一个订单提交流程,就先在纸上或者脑子里排好顺序:登录 - 进入商品列表 - 搜索商品 - 查看详情 - 加入购物车 - 提交订单 - 支付 - 查看订单状态。录的时候严格按照这个顺序一步步来,每做完一个动作稍微停顿一两秒,让浏览器把该发的请求都发完,JMeter 完整捕获后再进行下一步。
为什么强调这个?因为 JMeter 录制是按时间顺序记录请求的,如果你在操作过程中频繁切换页面、刷新、点错按钮,录制出来的脚本里会混入大量无关请求,后面整理脚本的时候你还要一个个判断哪个是核心请求,非常浪费时间。录制的过程中,JMeter 的左侧树形结构会实时出现请求节点,你可以一边录一边瞄一眼,看请求有没有正常进来。
3.3 HTTPS 请求录制失败的高频原因
录制 HTTPS 请求时,如果发现 JMeter 里面没有捕获到请求,或者浏览器一直报“代理服务器出现问题”之类的错误,先不要急,按下面这个顺序排查,我遇到过的基本都能对上号。
第一,确认 JMeter 代理端口和浏览器代理端口是否一致。这个看起来简单,但真的会有人 JMeter 里填了 8888,浏览器那边填 8080,那肯定录不到。
第二,确认证书导入的浏览器和当前录制用的浏览器是同一种。这里特别提醒:有些人用 Chrome 导入证书,然后又拿 Edge 或者 Firefox 去录制,证书不通用,就会失败。特别是不用 Firefox 录制,它的证书库独立,很容易出这种低级错误。
第三,确认 JDK 版本。早期我用 JDK 8 录制 HTTPS 脚本时一切正常,但有些高版本 JDK 对 TLS 协议的支持有变化。如果你录制时浏览器立刻报“ERR_SSL_PROTOCOL_ERROR”之类的错,可以试试换 JDK 11 或者调整 JMeter 的系统属性来放宽 TLS 版本。
第四,检查杀毒软件和防火墙。有些杀毒软件会监测本机代理,拦截浏览器的代理流量。录制的时候可以临时退出安全软件,或者把 JMeter 加白名单,录制完再恢复。
4. 录制完成后的脚本清洗与优化
4.1 过滤无用的静态资源请求
录制完成后,线程组下面会有一大串请求,其中很大一部分是图片、样式表、脚本文件。这些静态资源在功能测试里无关紧要,在压力测试时又会增加无谓的负载,所以必须清理。
如果在录制前你已经在 HTTP 代理服务器的“排除模式”里加好了过滤规则,那这一步会轻松很多。但如果当时没加,现在也可以在录制完统一处理。选中线程组下面的请求节点,按请求路径排序,看到png、jpg、css、js、ico、woff结尾的请求,直接右键删除。
另外一个隐藏静态资源是接口里的埋点请求。很多网站会频繁上报用户行为数据,比如点击事件、页面停留时间、浏览轨迹等。这些请求在录制时也会被完整捕获,但它们并不是被测业务的核心链路,压测时可以不包含。判断方法很简单,看请求路径里有没有类似的 token:collect、report、track、log、analyse。
清洗的原则是:把自己关心的业务链路上的请求留下,其他全部清掉。不要怕删错,后面跑脚本的时候发现缺了什么再单独补请求就行。
4.2 参数化:录制的脚本不能直接压测
录好的脚本直接拿去压测一定会出问题,因为录制下来的参数值是写死的。比如登录请求里带着当时的用户名密码、时间戳、随机字符串、订单号等,这些值对不同的压测用户来说应该是变化的,写死的话,服务器很快就会发现异常,接口开始报错。
参数化最常用的做法是从 CSV 文件读取数据。比如你的接口需要一个手机号参数,你先准备一个phone.csv文件,里面放几十上百个手机号。然后在 JMeter 里添加“CSV 数据文件设置”,设置好文件路径和参数名称,比如变量名填phone。接下来在请求参数里把原来的手机号替换成${phone},这样每次循环就会从 CSV 文件里取一个新的手机号。
还有一种常见情况是关联。比如先登录拿到一个 token,后面的请求都需要带上这个 token。录制时 token 是写死在请求头里的,但压测时每个用户的 token 都不一样,这就要用到 JMeter 的正则表达式提取器或者 JSON 提取器。先从登录响应里提取出 token,存成变量,再在后续请求里用${token}引用。这是脚本录制到实际可用之间最重要的一步,宁可多花时间也要弄明白。
4.3 断言:让脚本自动判断结果对不对
录制脚本跑起来后,怎么知道请求到底成功没有?光看响应数据太费眼睛了,而且效率低。用断言来自动判断是标准做法。
最常用的是响应断言。点中某个请求,右键“添加 - 断言 - 响应断言”,在“测试模式”里选择“响应文本”,然后添加一个你确定会返回的字符串。比如登录接口成功后大概率会返回"code":0或者登录成功,那就把这两个词加到断言里。如果请求跑完没在响应里找到这个词,断言就会失败,在查看结果树里显示红叉,这样一眼就能看出哪些请求有问题。
性能测试里还会用到 Duration Assertion,也就是持续时间断言。比如一个接口要求必须在 500 毫秒内响应,超过就算不通过,那就在断言里设置 500ms。这在录制后的脚本优化阶段特别有用,可以直接看出每个请求的实际耗时是否达标。
4.4 调试用的查看结果树组件
录制完脚本首次跑通之前,一定要在测试计划里加一个“监听器 - 查看结果树”。它的作用是把每个请求的请求数据和响应数据原样展示出来,方便你逐条检查。
我自己的调试流程是:先单线程跑一遍脚本,然后打开查看结果树,逐个请求看响应内容,确认每个请求都拿到了正常响应。遇到红色报错的请求,先看“响应数据”标签页里的错误信息,大多数情况能直接从里面定位到是参数写死、缺少关联还是请求头不对。定位到问题就改,改完重新跑一遍,直到所有请求都是绿色通过,再进行后面真正的压测。
等脚本稳定并开始正式压测时,记得把查看结果树禁用掉,因为查看结果树会把每一个响应都完整保存下来,大量用户压测时会产生巨量的日志,导致 JMeter 本身性能下降,甚至内存溢出。
5. 录制与使用过程中的常见问题
5.1 问题排查速查表
下面这些是录制过程中出现频率最高的问题,我按症状把原因和解决办法整理成一个速查表,遇到问题直接查。
| 常见问题 | 可能原因 | 解决办法 |
|---|---|---|
| 浏览器打不开网页 | 代理已设置但 JMeter 代理未启动 | 先启动 JMeter 代理,再操作浏览器 |
| JMeter 中录不到任何请求 | 代理端口不一致或浏览器未走代理 | 核对 JMeter 与浏览器代理端口一致 |
| 登录页面能打开但后续请求失败 | HTTPS 证书未正确导入 | 重新导入 JMeter 生成的 CA 证书到受信任根证书库 |
| 录制到的请求里中文乱码 | 请求编码与 JMeter 默认编码不一致 | 修改请求的 Content Encoding 为 UTF-8 |
| 录完回放全部红叉 | 录制时参数写死,缺少关联 | 做参数化,用正则提取器或 JSON 提取器关联 |
| 代理端口被占用 | 上次代理没有正常停止 | 检查 8888 端口占用进程,或改用其他端口 |
| Firefox 始终提示证书无效 | Firefox 不走系统证书库 | 在 Firefox 证书管理器中单独导入 JMeter 证书 |
5.2 录制结果为空时的排查思路
录了几分钟,发现 JMeter 左侧树里一个请求都没有,这是我最经常被问到的场景。这里给一个排查的先后顺序,照着做能解决九成的问题。
先看 JMeter 代理服务器有没有在运行状态。如果日志里出现了异常堆栈,比如端口被占用,那就先解决端口问题。再看浏览器里的代理设置有没有生效,可以在浏览器地址栏输入http://ip138.com或者直接用浏览器打开一个简单页面,如果页面能正常加载,说明代理是通的。最后看证书是否影响到了 HTTPS 请求,把目标网站地址从https://临时改成http://再试一次,如果 HTTP 能录到而 HTTPS 录不到,那就是证书的问题,重新走一遍证书导入流程。
这个排查思路的核心是先区分是“代理没通”还是“代理通了但请求没录上”。如果代理没通,浏览器根本打不开网页;如果代理通了但录不上,那问题基本出在证书或者目标控制器配置上。
5.3 回放脚本时响应报错的典型情况
脚本录完、清理完成、参数化也做了,回放时仍然报错怎么办?这里说三个我踩得最深的场景。
第一个是登录失效。录制的登录请求里可能有时效性要求,比如一天后过期、验证码过期、token 过期。回放时虽然有参数化,但验证码如果是从 CSV 里读的静态值,而系统要求验证码实时生成,那就必须处理。最直接的方案是让开发提供测试环境专用的万能验证码,或者改用接口调用方式绕过验证码环节。
第二个是请求头缺失。浏览器发送请求时,会带上各种各样的请求头,比如Referer、Origin、User-Agent、Cookie等。录制下来的脚本里确实带了这些头,但有些是因为浏览器自动管理的,比如Accept-Encoding: gzip。JMeter 回放时不一定会自动处理所有头字段,某些字段缺失会导致服务器校验失败。遇到这种问题,对照录制请求和实际浏览器请求的请求头差异,把必要的头补上。
第三个是数据依赖没做关联。登录返回的 token 没有提取,后续请求还在用录制时的旧 token,那回放必然失败。解决思路就是前面说的 JSON 提取器或正则表达式提取器。
6. 从录制到压测的落地经验
脚本录制只是 JMeter 学习的一个入口,录好之后真正要做的是让脚本能稳定跑起来、能支撑起并发压力测试。我个人在实际操作中养成了一套固定流程,分享出来供你参考。
录制完成后我会先把脚本清洗干净,加上必要的断言和参数化,然后用单线程跑一遍,确认所有请求能正常通过。接着再逐步增加线程数,比如先 10 个并发跑一轮,观察 TPS、响应时间和错误率。这时候如果出现错误,就回过头去检查脚本,而不是直接加大并发量。很多新手做压测一上来就 1000 并发,脚本本身问题一堆,压出来的数据没有任何参考价值,还会把服务器打挂,完全是在给自己埋雷。
还有一点很重要:录制脚本时用真实账号和真实操作路径,不要刻意走极端。有些人为了让录制更快速,跳过了思考时间、连续快速点击多个按钮,这样录出来的脚本时间间隔太小,压测出来的数据会失真。真实用户操作是有停顿、有思考时间的,录制出来的脚本也应该带一些自然的间隔,压测结果才更有代表性。
最后再分享一个小技巧:如果你录制的是一套长期需要维护的测试用例,不要把所有东西都塞在一个线程组里。可以把登录单独放一个线程组,核心业务放另一个线程组,公共的数据准备和清理放第三个线程组,用线程组之间的顺序控制来串联。这样后期维护时,业务逻辑变了只需要改对应线程组,不会牵一发动全身。这是我踩过很多次坑之后总结出来的经验,希望对你有用。