
录制脚本这件事说大不大说小不小。我刚接触压测那会儿总觉得“录制脚本”是把浏览器操作变成JMeter脚本的捷径但真正动手才发现坑全藏在细节里证书没导入、代理没配对、脚本录出来一堆静态资源请求、录完跑压测直接报连接重置。这几年带着团队做过不少压测项目也帮别人排过很多录制相关的坑整理一篇完整的实操记录从原理到步骤再到避坑一次讲透。这篇内容适合刚接触JMeter、想通过录制快速生成测试脚本的人也适合已经会用JMeter但录制HTTPS总失败、脚本录完不会整理的测试工程师。看完你应该能独立完成一次“录制—整理—验证—可压测”的完整闭环。1. 先说清楚录制脚本到底是怎么回事很多新手有个误解以为录制脚本是JMeter“自动分析”了你的操作然后生成智能脚本。实际完全不是这么回事录制的本质是代理拦截。JMeter在录制时会在你电脑上启动一个HTTP代理服务器你在浏览器里的每一次请求都会先经过这个代理JMeter把请求内容URL、请求头、请求体、参数、Cookie等原样抓下来再翻译成对应的Sampler采样器。所以录制脚本这个动作本质上是“拦截并翻译HTTP通信”。至于你的业务逻辑、参数关联、动态令牌都靠后续整理。这意味着两件事第一不是所有请求都能录到。走系统级代理的流量能抓到但有些应用不走系统代理比如某些客户端、命令行工具就录不进去。第二录出来的脚本只是“草稿”不是“成品”。你点了10次页面可能录出200多个请求其中大半是图片、CSS、JS、字体等静态资源这些对压测业务接口来说往往要剔除。所以在动手录制之前先想清楚你的目标是什么是录一条完整的业务链路比如登录→查询→下单还是录单个接口业务链路建议用录制快速搭骨架再手动改单个接口不如直接用Badboy抓包或者直接手写HTTP请求录制反而效率低。我在实际项目里一般这么定复杂的多步骤业务流程5步以上、依赖动态参数先录制再整理简单接口1到3步直接手写或从抓包工具复制。记住这个原则你后面会省很多事。2. 环境准备别小看这一步录不录得成HTTPS全看它录制前的环境准备可以分为四个部分JDK和JMeter版本匹配、JMeter本身安装、必要插件如录制HTTPS所需证书、浏览器代理设置。很多人跳过其中某一步结果录制时各种怪问题。2.1 JDK与JMeter版本匹配JMeter是纯Java应用JDK版本和JMeter版本不匹配最典型的报错是“UnsupportedClassVersionError”或者启动后界面某些功能异常。建议用下表对照JMeter版本最低JDK要求推荐JDK版本JMeter 5.4及以下JDK 8JDK 8比较稳JMeter 5.5 - 5.6JDK 8JDK 8 / JDK 11JMeter 5.6.3JDK 8JDK 11 / JDK 17我本人的习惯是长期使用JDK 8配合JMeter 5.x系列大量项目验证过兼容性最稳。如果追求JSON提取器里更完善的语法支持或脚本中用到较新的Java特性可以上JDK 11但注意Beanshell等旧组件在JDK 11下偶有问题能用JSR223就不要用Beanshell。2.2 JMeter安装与启动下载地址上官网认准Apache JMeter的发行版不要从第三方站点下载来路不明的压缩包。拿到包后解压进入bin目录Windows双击jmeter.bat或者用管理员权限打开macOS/Linux执行./jmeter。这里有几个启动时的细节如果启动报错“java.lang.IllegalArgumentException: Unsupported class file major version”基本可以断定是JDK版本低于JMeter要求不用查别的。如果双击无法启动、窗口一闪而过先用命令行启动jmeter.bat或者jmeter -v通常能看到真实的报错信息。JMeter GUI模式本身比较吃内存录制阶段的资源开销不算大但正式压测不建议开GUI。录制阶段用默认堆内存即可压测前再调整jmeter.bat里的HEAP参数。2.3 插件安装录制HTTPS脚本或使用更好的录制体验需要关注两个东西安装证书bin目录下已有ApacheJMeterTemporaryRootCA.crt录制脚本启动代理时会自动生成和必要的插件管理器。插件管理器Windows直接下载plugins-manager.jar放进lib/ext目录重启JMeter后在“选项→Plugins Manager”中按需安装插件。录制本身不需要额外插件但如果你需要WebSocket、MQTT这类协议的录制能力就需要相应插件。热搜词里提到“jmeter下载mqtt插件”说明很多人需要在JMeter里压测MQTT服务这类场景就靠插件管理器解决。2.4 关键点让录制更干净的常用配置在正式开始录制之前我强烈建议你先在JMeter里做两个配置在bin/jmeter.properties中找到proxyhandler.httpsampling确认是否开启HTTPS采样默认情况下JMeter代理可以解析HTTPS但证书信任链必须装好。建议增加modeStandard或modeBODY这样录制的采样器在“察看结果树”中可以看到完整的请求体和响应体方便录制后确认内容。配置完成后启动JMeter正式进入录制流程。3. HTTP录制完整步骤从创建脚本录制器到跑通首条脚本这里以最常用的HTTP协议为主HTTPS的证书问题在下一节专门讲。3.1 创建测试计划与线程组打开JMeter后选中“测试计划”右键添加“线程组”。线程组里的线程数在录制阶段设1个就够了录制只是为了抓请求不是为了压测。但线程组的命名建议直接体现业务场景比如“录制-登录查询下单”这样后面整理时一眼能认出归属。3.2 添加HTTP代理服务器关键一步来了。在“测试计划”上右键选择“添加”→“非测试元件”→“HTTP代理服务器”。这个元件就是录制的中枢。代理服务器的核心配置项如下配置项推荐值说明端口8888默认8888如果被占用可改成其他空闲端口HTTPS Domains空或填写目标域名不填则默认拦截所有HTTPS域名目标控制器选择线程组录制的采样器会自动挂在指定线程组下分组每个组放入一个新的控制器按事务分组便于后期整理记录HTTP信息头勾选保留请求头信息添加断言可选录制阶段不建议加断言使用Regex提取可选录制阶段不建议开启会生成大量正则提取器干扰判断分组策略我在这里多说一句。默认“每个组放入一个新的控制器”会在每个事务浏览器标签页下建一个“简单控制器”把请求分门别类放进去。这个策略最贴近业务流程整理脚本时可以直接按控制器为单位保留或删除比“全部请求放一个平铺列表”好找得多。3.3 启动代理并配置浏览器点击“HTTP代理服务器”面板右下角的“启动”按钮JMeter会在本地启动代理服务并在bin目录下生成临时CA证书仅用于录制。这时需要在浏览器里设置代理指向127.0.0.1:8888。不同浏览器设置代理的路径差异不大这里以Chrome为例注意新版Chrome对系统代理依赖度高打开浏览器设置搜索“代理”进入“打开您计算机的代理设置”手动设置代理地址填127.0.0.1端口填8888点击保存设置好后浏览器访问任意HTTP站点JMeter代理面板下方的“记录”列表中会实时刷出请求这一步看到请求在跳就说明代理链路通了。3.4 执行操作停止代理配置好代理后在浏览器里按你的业务用例操作登录、填写表单、点击按钮、查询数据一步步走完。操作越接近真实用户录制出来的脚本越完整。操作完成后回到JMeter点击代理服务器面板上的“停止”按钮再关闭浏览器代理这一步很多人会忘导致之后浏览器上不了网。此时去线程组下面查看会发现已经生成了大量采样器。别被数量吓到这是正常的一个页面可能产生几十个请求。3.5 首次回放确认录制脚本能跑通右键线程组“添加”→“监听器”→“察看结果树”点击运行按钮看录制的请求是否有绿色回调。假如全是绿色恭喜你录制链路基本没问题假如有红色请求先不要急着怀疑录制去“察看结果树”看响应体里的具体报错大部分情况是登录态的Cookie或Token问题这在后面的脚本整理阶段会专门解决。我第一次录制时犯过一个低级错误录制完直接在JMeter里点运行结果返回“401 Unauthorized”。后来检查才发现录制时的登录态已经过期了操作和回放间隔太久重新走一遍录制流程就好了。所以如果你回放失败先确认浏览器录制时的登录态是否还在有效期内再做其他排查。4. HTTPS录制证书问题一次讲透HTTPS录制是很多新手卡壳的地方。热搜词“jmeter录制https脚本”和“jmeter安全证书”热度很高说明这是普遍痛点。HTTPS和HTTP录制的本质区别在于HTTPS涉及到CA证书的信任JMeter作为中间人需要生成自己的CA根证书并且让浏览器信任它才能解密HTTPS流量。4.1 获取JMeter的CA证书启动代理之后JMeter在bin目录下会生成一个叫ApacheJMeterTemporaryRootCA.crt的证书文件也有可能是ApacheJMeterTemporaryRootCA无扩展名需要手动加.crt。这个文件的位置可以在jmeter.properties里通过proxy.cert.directory修改默认是bin目录。4.2 将CA证书导入浏览器/系统信任库Windows系统操作比较简单双击这个.crt文件选择“安装证书”存储位置选“本地计算机”然后选择“将所有证书放入下列存储”点击“浏览”选择“受信任的根证书颁发机构”按提示完成导入。macOS系统操作也很方便双击证书文件钥匙串访问会弹窗把证书加入“系统”钥匙串然后在证书列表中双击刚刚导入的证书展开“信任”把“使用此证书时”改为“始终信任”关闭并输入系统密码确认。Android手机如需录制App的HTTPS流量把证书文件传到手机里在设置中搜索“证书”或“加密与凭据”选择“安装证书”类型选“CA证书”确认安装即可。iOS系统不展开说因为仅限HTTPS录制采用的是针对iPhone的代理配置方式需要额外在App中信任。4.3 浏览器代理里的HTTPS处理证书导入后关键一步是在浏览器代理设置里勾选“对https地址也使用代理服务器”部分浏览器这个选项在系统代理中默认开启有些需要手动。如果你用的浏览器不支持直接控制HTTPS代理可以考虑为浏览器配置PAC脚本或使用支持全局代理的插件。4.4 HTTPS录制的几个经典报错报错/现象原因解决方法浏览器显示“您的连接不是私密连接”CA证书未导入或导入的不受信任重新导入证书到受信任根证书颁发机构JMeter里录制的HTTPS请求全部是红色响应内容为空代理未捕获HTTPS流量或证书导入位置错误确认证书信任设置、确认代理设置覆盖HTTPS“Unable to negotiate SSL”JMeter与目标服务器SSL握手失败检查JMeter所在机器的JDK版本升级或切换JDK录制时页面打不开HTTP站点正常证书未被浏览器信任重新在浏览器/系统里信任JMeter CA证书4.5 实测经验证书问题排查链路如果你遇到HTTPS录制失败按下面这个顺序排查可以少走很多弯路先去浏览器的“不安全连接”页面看具体报错是“证书不受信任”还是“证书过期”。查看JMeter的代理面板“记录”区域有没有出现请求如果完全没有请求先排查代理配置别急着看证书。如果请求出现了但是全红看窗口输出里的SSL相关报错再检查证书是否被信任。确认证书文件名是否正确。我同事遇到过证书生成在bin目录里但文件名少了扩展名直接把整个文件拖入浏览器安装结果提示“无法识别”加个.crt后缀就好了。清理浏览器缓存和SSL状态缓存重试。有些场景下浏览器缓存了旧证书状态会导致新的JMeter证书不生效。另外一个容易被忽略的点JMeter代理启动时生成证书是有时效的。如果你多次启动代理JMeter会尝试复用同一个证书但如果证书过期或损坏可以删掉bin目录下的ApacheJMeterTemporaryRootCA.crt和对应的私钥文件一般是同目录下的.key文件重新启动代理会生成新的证书。5. 录完的脚本不能直接用整理、参数化、关联的完整处理录制大概率会产生大量冗余请求。如果你拿刚录完的脚本直接压测通常会出现几个问题一是静态资源请求大量堆积压测请求数虚高二是动态参数Token、Session、时间戳没有处理并发一上来就报错三是脚本结构混乱后期维护困难。所以录制后一定要做脚本整理。5.1 脚本瘦身剔除静态资源与辅助请求识别哪些请求该删有个简单原则不是业务核心链路的请求且不携带业务状态都是静态资源或辅助请求。典型包括.jpg、.png、.css、.js、.woff、.ico、.gif、.svg等文件资源请求。另外页面埋点、统计上报、第三方广告等请求通常也与被测业务无关可以一并删除。具体操作时在“察看结果树”里看到URL后缀是图片或静态资源右键“禁用”而不是“删除”。禁用后如果后续压测发现某个禁用请求其实是业务依赖恢复勾选即可。用“禁用”代替“删除”是我在整理脚本时最推荐的做法因为禁用后脚本还能在“察看结果树”里看到请求信息需要恢复时点一下勾选就行。录制完的脚本如果请求数量还是很大可以在“HTTP代理服务器”的“请求过滤”中使用正则表达式排除.*\.(js|css|png|jpg|gif|svg|ico|woff|ttf).*下次录制时这些静态资源就不会被录进来。5.2 参数化从CSV文件读取用户数据压测100个并发用户如果全部用同一个账号后端大概率会触发限流或风控也测不出真实场景。参数化的本质是把脚本里的写死的数据提取成变量让每个虚拟用户用不同数据。具体步骤准备CSV文件格式类似username,password首行为列名或按序排列。在测试计划或线程组下添加“配置元件”→“CSV数据文件设置”。配置项里填上CSV文件路径、变量名如username、分隔符默认逗号、碰到文件结束符是否循环建议勾选“循环”、是否共享模式一般用“所有线程”。在HTTP请求的“参数”中用${username}引用变量。需要特别注意编码问题。CSV文件如果含有中文建议另存为UTF-8编码不带BOM并在“CSV数据文件设置”中文件编码填UTF-8否则会出现乱码登录直接失败。5.3 关联动态参数的提取与传递录制脚本最大的坑是动态参数。录制时Token、SessionId、时间戳都是登录时从服务器返回的直接回放往往因为令牌过期或不存在而失败。关联就是让脚本能从某个请求的响应中提取动态值并作为后续请求的参数。JMeter常用的提取工具是“后置处理器”→“JSON提取器”适用于JSON响应和“正则表达式提取器”适用于任意文本。举一个最典型的场景登录接口返回一个token字段后续接口需要在请求参数携带token步骤如下在登录请求上右键添加“后置处理器”→“JSON提取器”。变量名称填tokenJSON Path表达式填$.data.token根据实际响应结构调整匹配数字填1。在后续请求的参数中用${token}引用。正则提取器的写法大同小异正则表达式填token:(.*?)之类模板填$1$匹配数字填1。这里要提醒一句能用JSON提取器就不要用正则正则对响应格式变化更敏感一旦服务端字段顺序调整或加个空格脚本就可能失效。我整理过一个下单链路脚本登录接口返回的token在3分钟后过期而压测设了5分钟的持续运行时间导致后面的下单接口大量失败。解决方法是在脚本中用循环控制器或Random定时器维持登录态刷新或者将业务链路的思考时间缩短让压测在token有效期内完成。这类坑在真实项目里很常见整理脚本时务必关注动态值的有效期。5.4 事务控制器与取名规范脚本整理完之后给每个业务步骤添加“逻辑控制器”→“事务控制器”把登录、查询、下单等请求分别包进去。事务控制器可以帮助你在聚合报告里按“事务”维度查看响应时间压测报告更立体。命名规范方面我的建议是控制器用业务名称采样器用“序号接口名简要作用”比如“01-登录接口-获取token”。这样几百个请求的脚本别人一眼能看懂后面维护成本大幅降低。6. 用察看结果树和断言验证录制脚本的正确性脚本整理完下一步是验证跑一次确认所有请求都是绿的并且绿得不只是状态码响应内容也正确。这里“响应内容正确”往往是新手最容易忽略的点——接口返回200不代表业务成功可能响应体里是个错误码。6.1 察看结果树的正确用法“察看结果树”监听器在录制阶段和验证阶段的作用不同。录制阶段用它看请求是否捕获成功验证阶段主要看三样东西HTTP状态码2xx和3xx一般算正常4xx和5xx需要排查。响应内容是否包含关键业务字段比如登录后是否返回了token、userId。请求参数是不是正确替换了变量${token}是否被真实值替换一旦看到请求参数里还有未替换的${xxx}说明变量引用有误。查看请求参数是否成功替换的办法在察看结果树里选中请求切到“请求体”标签页看POST请求体里的具体内容。如果还有${}形式的变量说明提取器没生效或变量名拼错了。6.2 断言让脚本自己判断正确性验证阶段可以加断言也可以在压测阶段保留断言让JMeter在压测过程中自动标记“业务失败”的请求。不过断言不是越多越好断言越多压测性能开销越大。建议只在关键业务节点上加断言。最常用的是“响应断言”可以配置“包括”模式检查响应内容是否包含某个特定文本。比如登录接口断言包含code:0下单接口断言包含“下单成功”。具体步骤选中请求右键添加“断言”→“响应断言”在“要测试的模式”里添加需要匹配的内容模式匹配规则选“包括”同时可以勾选“自定义失败消息”这样压测报告里能直接看到失败原因。特别注意响应断言的正则匹配是“匹配整个模式串”默认.*不会自动补全首尾。所以如果你想只匹配“成功”这两个字模式填成功即可不需要写.*成功.*但如果你用了正则语法做复杂匹配要注意.不会匹配换行符。6.3 验证清单什么算“脚本可以压测了”整理完脚本跑一遍单线程验证符合以下条件再进压测所有核心业务请求返回绿码且响应内容断言通过。没有未替换的${}变量。脚本中的登录态、Cookie、Token能维持整个业务流程走通。参数化文件中的数据量能够覆盖计划并发数不会出现数据用尽或循环冲突。满足这四条脚本基础质量就有了保障。7. 录制压测中的高频问题与排查方法最后把我在实际项目和帮人看问题过程中积累的常见问题集中写一下。这些问题很多不是录制本身的问题而是录制前、录制后没注意细节导致的但搜索引擎热词里都在搜说明踩坑的人非常多。7.1 浏览器代理设置后无法上网或页面白屏优先检查JMeter代理服务器是否处于启动状态。代理启动后浏览器所有流量都走本地代理一旦JMeter关闭或代理没开浏览器就会断网。操作顺序很重要先启动JMeter代理再配置浏览器代理停止录制时先关代理再恢复浏览器代理。另外有的浏览器如Firefox自带代理设置覆盖了系统代理需要单独在浏览器里配置。7.2 录制下来的请求在“察看结果树”中全是HTTP 404这个常见于前端是单页应用SPA的场景。SPA页面的路由跳转往往通过JavaScript完成请求可能是相对URL在JMeter录制结果里会变成路径缺失或拼接错误。解决方案是录制完成后检查请求URL手动修正为完整地址或者干脆不用录制直接在开发者工具Network面板里找到真正的XHR请求复制信息到JMeter中手动建请求。7.3 “java.io.IOException: Error writing to server”怎么破这个报错在压测过程中很常见原因是JMeter向目标服务器发送数据时I/O异常通常跟网络不稳定、服务器连接数打满或请求体过大有关。排查链路看压测机与目标服务器之间的网络是否丢包。看后端连接数是否达到上限如果超了并发连接会有大量这类错误。看是否踩了服务器防火墙或负载均衡的流量限制。适当调大JMeter的socket.keepalive相关参数但治标不治本根因一般不在JMeter。7.4 录制登录接口出现“__RequestVerificationToken 未提供必要的防伪标记”很多基于ASP.NET MVC或Web框架的应用有CSRF/XSRF防护机制页面里会埋一个隐藏的__RequestVerificationToken字段提交表单时必须带回。录制脚本如果只录了POST请求但没带上这个token字段回放就会报这个错。解决方式是用正则或JSON提取器从登录页面的响应里提取隐藏字段的值拼到POST请求体里。具体提取正则可以参考name__RequestVerificationToken typehidden value(.*?)。这类防伪令牌是典型的“录制脚本必须做关联”的场景也是检查脚本是否真正整理好的试金石。7.5 压测时请求乱序或并发数上不去录制脚本回放是单线程顺序执行压测时如果没加“同步定时器”即集合点线程组里的每个线程是会按自身节奏跑的可能出现请求顺序和录制时不一致。如果想要所有并发用户同时发起某个请求可以在该请求前添加“同步定时器”设置同步用户数等于线程数超时时间按需设置。并发数上不去优先看JMeter本身的运行机器负载CPU、内存、网络、被测服务器的承受能力以及本机是否开启了GUI监听器。压测阶段强烈建议以命令行模式运行jmeter -n -t 脚本.jmx -l 结果.jtl -e -o 报告目录GUI里加的察看结果树聚合报告等监听器会严重拖慢Jmeter吞吐。7.6 CSV参数化文件每个线程分块取值的问题热搜词里有一条“jmeter在同一个csv参数化文件中每个线程分块取值”这个需求一般是想让不同线程组或不同线程取CSV的不同区块避免数据冲突。实现方式在“CSV数据文件设置”中共享模式选择“当前线程组”或“所有线程”再配合“线程数”和循环次数来控制每个线程读取的行数。如果追求更精细的分块比如线程1读1-100行线程2读101-200行可以在脚本中用__CSVRead()函数或配合BeanShell/JSR223读取CSV并在变量名中带上线程编号${__threadNum}做拼接定位。7.7 JMeter界面字体调整顺带说一下界面字体的调整。JMeter默认字体在部分高分屏下偏小修改bin/jmeter.properties里的jmeter.hidpi.modetrue和jmeter.hidpi.scale.factor2.0可以解决高DPI下模糊的问题具体缩放系数按需调整。字体大小则可以在“选项→外观”里换主题或在jmeter.properties里修改jmeter.user.properties相关的swing字体设置。7.8 JDBC 参数化与数据库关联脚本里如果涉及数据库参数化热搜词里也有“jmeter jdbc request参数化”常见两个场景把数据库查到的数据作为后续接口参数添加“JDBC Connection Configuration”和“JDBC Request”在JDBC Request里写查询SQL结果变量名填dbResults后续接口用${dbResults_1}引用第一行第一列的值。接口返回的数据反查数据库验证可以添加“JDBC Request”后加断言查询结果为空则失败。JDBC参数化最大的坑是数据库连接数。并发大时JDBC连接池太小会报Cannot create PoolableConnectionFactory建议根据并发规模调大连接池最大连接数。写在最后关于录制脚本的几点个人经验录制脚本只是JMeter性能测试链路里“造车”的开端真正决定压测结果有效性的是脚本整理环节对动态参数、业务链路的处理。我个人碰过太多“录完就跑”导致压测数据完全失真、被开发质疑的案例所以特别强调一遍录制的产物是草稿整理后的脚本才叫脚本。另外提一个小技巧录制前先在浏览器打开开发者工具的Network面板把请求分类方式切到“Fetch/XHR”操作业务时专门记录这些接口的调用顺序和参数格式。录制出的脚本如果哪里不对劲用Network面板里的原始请求做对照一眼就能发现录制器丢参数或漏请求的问题。录制脚本是入门JMeter的一个重要里程碑也是理解HTTP请求细节的天然教材。把录制、整理、验证这套流程走顺往后无论手写脚本、调试接口、排查压测报告你都会比没走过这条路的人快不少。