干性能测试这行你迟早会遇到一个让人头疼的场景业务方丢给你一个Web端流程动辄十几步操作——登录、选查询条件、翻页、勾选、提交、再回到列表页刷新——真要让你自己对着抓包工具一个个接口去拼脚本光参数关联和请求顺序就能折腾小半天。JMeter录制Web端压测脚本这个功能说白了就是帮你把浏览器里的真实操作自动变成JMeter脚本省掉手工构造HTTP请求的重复劳动。如果你是刚接触性能测试、或者被复杂业务流程折磨过的新手这篇就把录制环境配置、HTTPS证书处理、脚本整理这几个最核心的环节一次讲透照着做就能录出一条能跑的压测脚本。录制功能本身不复杂但实际用起来坑不少HTTPS证书装不上、静态资源刷屏、录制完脚本一堆404……这些我都踩过。下面把我的完整操作步骤和排查经验整理出来按顺序走基本不会卡壳。1. 录制方案设计与思路拆解1.1 为什么要用代理录制而不是纯手工写脚本我见过不少同事一上来就鄙视录制功能觉得手写脚本才显得专业。这个观点我部分同意——手写脚本更灵活、可控性更强但前提是你对业务流程足够熟悉、对HTTP协议足够敏感。现实情况是很多Web业务的前端交互非常复杂比如页面里嵌了iframe请求跨域跳来跳去某个按钮触发了一连串异步请求顺序和间隔不好把握有加密参数、动态token手工构造很容易漏字段接口文档不全后端实习生写的接口连命名都看不懂这种情况下代理录制的价值就很明显了你只需要打开录制开关、在浏览器里正常操作一遍业务JMeter就能把过程中的HTTP请求按时间顺序抓下来。它不关心你懂不懂协议只看真实浏览器发出了什么请求、带了什么参数录出来的脚本天然就是“真实流量”的映射。但要注意录制只是一个起点不是终点。录出来的脚本里有大量静态资源请求、Cookie处理、动态参数关联这些都还需要后续整理。我的经验是复杂业务流程用录制打底然后在录制脚本基础上做参数化、断言、关联的二次加工效率远高于从零手写。1.2 录制原理JMeter是怎么“偷看”浏览器流量的用一句话解释录制原理JMeter把自己伪装成一个中间代理服务器浏览器的所有请求先经过它它把请求内容复制一份记下来再转发给真正的服务器。这个过程有点像快递中转站。你寄快递浏览器发请求的时候快递员JMeter代理会先看一眼包裹内容、抄一份留底生成脚本然后把包裹继续送到目的地目标服务器。服务器返回的响应同样经过快递员转交给你所以快递员也能看到响应内容——这就是为什么JMeter能录到完整的请求和响应数据。具体到实现层面JMeter里实现录制核心是一个叫HTTP代理服务器HTTP Proxy Server的组件新版JMeter5.x系列里它位于“测试计划”右键菜单下。你配置一个本地端口比如8888把浏览器的代理指向这个端口JMeter就会在这个端口上监听所有经过的HTTP和HTTPS请求。1.3 录制工具选型JMeter自带录制和外置抓包工具怎么选做Web端压测脚本常见的方案不止JMeter录制一种我列个对比表供你参考方案优点缺点适用场景JMeter自带代理录制一键生成脚本与JMeter无缝集成脚本噪音多需要大量清理快速生成复杂业务流程脚本Fiddler/Charles抓包 手动构造请求信息直观可以完整看到请求头、响应体生成脚本仍要手动操作效率低需要精细分析单个接口时BrowserMob Selenium可以自动化操作浏览器并同步录制配置复杂学习成本高需要录制大量场景、自动化回归时JMeter Chrome扩展直接在浏览器里录制操作简单插件更新不及时兼容性一般简单场景快速试用如果你只是要一条能跑的压测脚本JMeter自带录制是性价比最高的选择不用装额外工具录完直接在JMeter里改。上文提到的Fiddler这类抓包工具更适合做单接口调试和排查两者不冲突我在实际项目中经常配合使用。2. 录制前的环境准备与配置2.1 JDK和JMeter版本匹配别在这栽跟头很多人卡在第一步其实是JMeter版本和JDK版本不匹配。JMeter 5.6.x要求JDK 8以上但我实测最稳的是JDK 11或JDK 17配JMeter 5.6.3。如果你用的是JDK 21可能会遇到一些不明所以的报错比如“UnsupportedClassVersionError”——这就是版本太新、JMeter还没跟上导致的。安装JDK之后记得在系统环境变量里配置JAVA_HOME到JDK安装目录然后命令行执行java -version确认能识别。Windows用户要特别注意如果你之前装过其他Java版本环境变量里可能残留旧的路径指向最好把JAVA_HOME删了重建避免JMeter启动时加载了错误的Java版本。JMeter本身是绿色软件从官网下载压缩包解压就能用。Windows双击bin/jmeter.batLinux/Mac执行bin/jmeter.sh。官方下载页面有时候加载慢建议直接找Apache官网的镜像地址选择.zip格式的二进制发行版。不用安装但建议放在一个路径里不要有中文和空格的目录比如D:\tools\apache-jmeter-5.6.3不然启动或录制时可能出奇怪问题。2.2 浏览器准备为什么我推荐独立Profile录制录制Web端脚本浏览器建议用Chrome或Edge。但这里有个容易被忽略的细节不要直接用日常使用的浏览器Profile去录制因为你日常浏览器装了各种插件、留有各种登录态会导致两个问题浏览器插件比如广告拦截会干扰请求拦截一些关键请求导致录不全历史登录态、Cookie会让录制过程掺杂预加载、缓存请求脚本噪音多我的做法是给录制单独开一个Chrome用户目录。Windows下可以这样启动chrome --user-data-dirD:\temp\jmeter-chrome-profile或者在JMeter代理启动后手动配置浏览器代理用一个干净的隐身窗口操作。重视一点录制时浏览器缓存要清理干净否则很多资源直接从本地缓存加载根本不会走代理录不到请求。实测中最常见的问题就是录出来的脚本只有几个请求找半天原因发现是缓存惹的祸。2.3 明确录制目标梳理业务流程和关键接口不要打开浏览器就开始录。我吃过这个亏录了5分钟的操作生成了一堆脚本回头一看关键流程没走全只能重录。正确做法是录制之前先在纸上或记事本里把业务操作步骤列出来比如打开登录页面输入账号密码点击登录进入列表页设置查询条件点击查询点击第一行数据的详情按钮在详情页做某项操作退出登录每一步对应哪些关键接口要做到心里有数。这样录制的时候你会主动去关注请求是否录到、顺序是否正确而不是录完事后再回看脚本猜流程。3. JMeter代理录制的完整配置流程3.1 新建测试计划并添加代理录制组件打开JMeter后第一步先建测试计划。这里有个新手容易搞混的点JMeter 5.x里有两个地方可以添加录制组件——测试计划右键菜单和工作台WorkBench。工作台是早期版本的设计现在官方推荐直接在测试计划下添加HTTP代理服务器这样录出来的脚本会自动生成到指定位置。具体操作点击左侧“测试计划Test Plan”重命名为你的业务名比如“电商下单流程压测”右键测试计划 → 添加 → 非测试元件 →HTTP代理服务器在HTTP代理服务器界面重点配置几个参数见下文如果不小心加了“工作台”模式的代理服务器也没大问题只是录出来的线程组是游离在测试计划外的需要手动拖拽到测试计划里。有这个概念就好。3.2 HTTP代理服务器关键参数配置详解打开HTTP代理服务器配置界面后我按重要性依次说明端口Port默认是8888这个端口是JMeter代理监听的端口浏览器代理也要指向这个端口。如果8888被占用改成其他高位端口比如18080、19090都行。目标控制器Target Controller这里选“测试计划 线程组”意思录制的请求会直接生成到指定线程组下。设置方法是你提前建好一个线程组比如“业务流程脚本”然后在这里通过下拉框选中它。我在没建线程组时录制过结果所有请求直接生成到了测试计划根目录还得手动整理很麻烦。分组Grouping建议选择“每个组放入一个新的控制器”。这个选项会把一个业务流程中的请求自动分组比如登录的请求放在一个“登录”控制器里查询的请求放在“查询”控制器里看着清晰后续做事务控制也方便。如果选“每个组放入新的线程组”每一轮操作都会新建线程组脚本会非常臃肿不推荐。HTTP Sampler settings这里有几个选项容易被忽略其中“Type - Java”是默认选项适合大多数情况“Redirect Automatically”建议勾选“Follow Redirects”建议勾选“Download embedded resources”建议不勾选。为什么要这样重定向Redirect如果没勾选脚本里会出现301/302响应请求链路不完整“Download embedded resources”勾选后会把图片、CSS、JS都录下来脚本会膨胀好几倍这部分我们后面统一清理。排除模式Exclusions这是录制配置里的关键环节。在“排除模式”区域添加正则表达式把静态资源和无关域名排除掉。我常用的排除内容.*\.js.* .*\.css.* .*\.png.* .*\.jpg.* .*\.gif.* .*\.ico.* .*\.woff.*注意排除模式是正则表达式不是通配符。很多人写*.js发现没效果就是因为正则里*代表的是“任意次数”不是“任意字符”。正确写法是.*\.js.*表示“匹配以.js结尾的任意字符组合”。如果录制时不想排除任何内容也可以先不填录制完统一清理但那样脚本里会大量静态资源请求找关键请求时很费眼。3.3 配置浏览器代理让流量流经JMeterJMeter代理启动后浏览器要配合设置代理才能让流量经过。这里分几种情况方式一手动配置浏览器代理每个浏览器独立设置以Chrome为例设置 → 隐私设置和安全性 → 代理 → 手动设置代理 → 打开“使用代理服务器”地址填127.0.0.1端口填8888或你设置的端口然后保存。注意勾选“对本地地址绕过代理”选项否则访问本地服务也会走代理会造成代理循环。方式二使用浏览器插件快速切换推荐我平时用SwitchyOmega插件管理代理配置。先在插件里新建一个代理情景模式配置HTTP和HTTPS代理都是127.0.0.1:8888然后通过插件一键切换代理开启和关闭。相比手动改浏览器设置这种方式最大的好处是录完就能秒切回“直连模式”避免代理一直开着导致其他网站访问异常。有个细节必须提醒录制HTTPS网站时浏览器代理设置里既要设置HTTP代理也要设置HTTPS代理。很多人漏设HTTPS代理结果只能录到HTTP请求HTTPS请求全部丢失。3.4 启动录制完整操作顺序代理配置完成后按下面的顺序操作每一步都有明确目的在JMeter的HTTP代理服务器界面点击“启动”按钮。此时会提示“JMeter会生成一个根CA证书”点击确定。如果端口被占用会直接报错需要先换端口。看到JMeter日志区域出现“Proxy up and running”字样确认代理启动成功。浏览器切换代理到127.0.0.1:8888注意顺序先启动JMeter代理再切换浏览器代理。访问录制目标URL正常操作业务流程。每一步操作稍作停顿避免操作太快导致请求来不及被记录尤其是页面跳转和异步请求的间隙等待页面响应完成后再进行下一步。操作结束后先切换浏览器代理回直连模式再回到JMeter点击“停止”按钮。到目标控制器线程组下查看生成的请求列表确认关键请求都在。这个顺序里最容易犯的错误是浏览器代理先切过去了JMeter代理还没启动结果浏览器请求直接报了“代理服务器拒绝连接”——不是你的配置错了是顺序反了。养成“先启动JMeter代理再切换浏览器代理”的习惯能少踩很多坑。4. HTTPS脚本录制的证书处理与常见报错4.1 为什么录HTTPS必须导入JMeter根证书Web端现在是HTTPS的天下。HTTPS流量是加密的JMeter如果想“偷看”内容就必须让浏览器信任JMeter自己签发的证书。这个证书在JMeter首次启动代理时生成文件名叫ApacheJMeterTemporaryRootCA.crt默认位置在JMeter的bin目录下。浏览器如果没安装这个证书访问HTTPS网站时会提示“您的连接不是私密连接”“证书无效”等警告请求也就无法正常通过代理。所以录HTTPS脚本第一步是把这个证书导入到浏览器的“受信任的根证书颁发机构”里。4.2 证书导入的具体操作步骤以Chrome为例打开JMeter安装目录下的bin文件夹找到ApacheJMeterTemporaryRootCA.crt。双击证书文件打开“证书导入向导”点击“下一步”。存储位置选“本地计算机”然后点“下一步”。页面会提示“即将安装证书”此时先不要直接点“完成”需要点“浏览”选择“受信任的根证书颁发机构”再点“确定”。点击“下一步”→“完成”系统弹出“安全警告”点击“是”。导入完成后重启浏览器让证书生效。注意一个容易混淆的地方有些教程会让你把证书导入到“个人”证书存储区那是错的。如果导入“个人”区域访问HTTPS时依然会提示证书无效。必须是“受信任的根证书颁发机构”。4.3 HTTPS录制常见报错与解决对照我整理了录制HTTPS场景下出现频率最高的几个报错都是实战踩过的报错现象可能原因解决办法浏览器提示“证书无效/连接不安全”证书未导入或导入位置错误按上面步骤重新导入到“受信任的根证书颁发机构”JMeter无任何请求记录浏览器页面打不开代理端口冲突或代理配置未生效检查JMeter端口是否被占用换端口试确认浏览器代理指向127.0.0.1且端口一致报错javax.net.ssl.SSLException: ...JMeter与Java版本不兼容或证书时区问题升级JDK到11/17删除bin目录下旧证书重新生成部分HTTPS请求录到了部分丢失跳过浏览器代理设置中的HTTPS代理项浏览器代理设置中把HTTPS代理和HTTP代理都填上127.0.0.1:8888请求记录出现但响应内容显示乱码编码问题一般是UTF-8和GBK混用在监听器“查看结果树”里选择正确的响应编码或在HTTP请求中指定编码4.4 录制过程中证书的常见坑一次只装一次一个很容易被忽略的细节JMeter代理每次重新启动生成的临时证书都可能变化。如果你今天用着没问题改天重启电脑后录HTTPS又提示证书无效不要急着到处找原因——优先去JMeter bin目录看看证书文件是否被更新了如果是删掉浏览器里旧的根证书重新导入一次就好。另外公司电脑如果是域环境浏览器可能被管理策略限制了手动导入证书这时候可以联系本地管理员处理或者换用带独立用户目录的浏览器实例录制。5. 录制后脚本的整理与增强从“能跑”到“跑得对”5.1 清理静态资源和无效请求给脚本瘦身录完的脚本通常会有几十上百个请求但真正有压测价值的核心接口可能只有五六个。第一步就是瘦身。打开生成的线程组你会发现HC里有一堆JS、CSS、PNG、字体文件请求。在JMeter的查看结果树里它们大多返回200但压测时这些静态资源会给服务器带来大量无效负载干扰你对核心接口性能的判断。清理方式有两种方式一直接在脚本里删除逐个选中静态资源请求右键删除。缺点是请求多时很费时间。方式二利用JMeter的“包含/排除”逻辑重新录制推荐回到HTTP代理服务器配置界面的“排除模式”把静态资源正则加进去重新录制一遍。我常用的排除正则前面已经列过能过滤掉90%以上的静态资源请求配合“Download embedded resources”不勾选脚本会干净很多。清理完静态资源后还要注意删除那些录制时产生的探活请求比如favicon.ico浏览器自动请求的网站图标以及登录跳转前的一堆302转跳请求中的无关部分。保留核心业务请求冗余越少后续维护成本越低。5.2 参数化和关联让脚本能应对不同用户和数据录制下来的脚本所有参数都是固定的——用户名是录制的那个订单ID是录制时的那一个。直接拿这种脚本去压测相当于所有并发用户都在用一个账号、操作同一条订单压出来的结果没有参考价值。必须做两件事参数化和关联。参数化就是把固定的值变成变量。比如在“HTTP请求”的“参数”列表里把用户名改成${username}然后在“用户自定义变量”组件里定义一组username变量或者用“CSV数据文件设置”从外部文件读取多组用户数据。这样每次请求都会用不同的用户名。关联则用于处理前后请求动态变化的参数比如登录接口返回的token后续的查询接口需要用这个token才能访问。录制脚本里token是写死的直接压测会导致所有请求都拿着同一个失效的token大量报401/403。关联的标准操作是在返回token的请求下添加正则表达式提取器或JSON提取器把token提取到变量里然后在后续请求中引用这个变量。比如用JSON提取器JSONPath表达式$.data.token 变量名mytoken 默认值NOT_FOUND然后在后续请求的头管理器里把Authorization字段的值改为Bearer ${mytoken}。这里要注意提取器的作用范围如果你放在某个请求下面它只对这个请求及其子请求生效如果放在线程组下则对这个线程组里所有请求生效。关联和参数化是录制脚本从“玩具”变成“工具”的关键一步也是性能测试中最体现功底的部分。5.3 添加断言和监听器让结果可判断清理和参数化之后脚本已经能跑起来了但跑完怎么看结果对不对需要加断言。常用的断言有两种响应断言检查响应内容是否包含关键字段。比如登录请求后响应体应该包含“登录成功”或者返回的JSON里某个字段值为true。添加位置是HTTP请求的右键菜单 → 添加 → 断言 → 响应断言。在“测试模式”里填关键内容选“匹配”即可。注意不要写全串匹配选“包含”模式更稳妥——因为响应体里往往有多余的换行、空格全匹配容易误判。持续时间断言检查请求是否在指定时间内完成。对于性能测试这个断言比响应内容断言更直观它直接告诉你“超过3秒的请求就算失败”。添加方式同理在断言里填最大响应时间毫秒。监听器方面查看结果树用于调试时看单次请求的详细数据聚合报告用于压测结束后看整体指标平均响应时间、吞吐量、错误率。记得查看结果树在正式压测时要禁用否则它会收集所有响应数据严重占用内存影响压测结果。5.4 线程组设置模拟真实并发场景录制脚本默认线程组只有1个线程、执行1次这显然不是压测。根据业务需求调整线程组的核心参数线程数Number of Threads模拟并发用户数。比如50个用户同时操作。Ramp-Up时间Ramp-Up Period在多少秒内启动这些线程。设为0会瞬间高负载启动容易把服务器打崩建议根据场景设置为10~20秒模拟用户逐步进入。循环次数Loop Count每个线程执行脚本的次数。可以勾选“永远”配合调度器如压测5分钟使用也可以设置固定次数。一个常用的计算逻辑如果目标是50并发持续运行5分钟可以设置线程数50循环次数勾选“永远”在调度器配置里设置持续时间300秒然后在运行结束后再统计聚合报表。这样压测的平稳度可控也不会让脚本无限制跑下去。6. 常见问题与排查技巧实录6.1 录制后请求只有几条关键接口没录到这是录制场景最高频的问题。头号原因是浏览器缓存——页面资源从缓存读取不经过代理。解决方法是录制前在浏览器里按CtrlShiftDelete清空缓存或者开启浏览器“无痕模式”录制。无痕模式下缓存默认失效请求都会走代理录到的内容更全。第二个原因是代理排除规则误伤。检查一下浏览器代理设置里是否勾选了“对本地地址绕过代理”如果目标URL是内网地址或localhost流量就不会走代理。这种情况取消勾选即可。第三是过滤规则写得太宽。JMeter的排除模式如果写了.*这种无差别正则会把所有请求都过滤掉一个都录不到。建议录制初期暂不配置排除规则等脚本生成后再精简尤其对于新手别一开始就追求“干净”而耽误了主流程录制。6.2 代理启动报“端口已被占用”这个报错很直接通常在JMeter控制台GUI上就会出现红字显示“BindException: Address already in use”或类似信息。解决方式换个端口比如把8888改成18080。先排查占用端口的进程Windows下netstat -ano | findstr 8888然后根据PID在任务管理器里结束对应进程Linux下用lsof -i:8888。注意有些安全软件比如部分企业管控软件会拦截本地端口监听如果换端口仍然报占位相关错误可以检查安全软件是否把JMeter拦截了。6.3 录制时浏览器页面上出现“ERR_PROXY_CONNECTION_FAILED”这个错误的意思是浏览器连不上代理。排查顺序确认JMeter代理已在运行日志区域有Proxy up and running提示。确认浏览器代理设置里地址、端口和JMeter设置一致。确认没有其他代理工具如Fiddler、Charles正在占用同一端口。我之前遇到过Fiddler和JMeter同时开着Fiddler抢占了8888端口导致JMeter代理看似启动、实际连接失败的情况。如果浏览器设置代理后访问普通网页都打不开说明代理规则把范围搞大了——检查是否同时设置了“对HTTPS地址也使用代理”并且确认JMeter代理确实监听在对应端口上。6.4 录制的脚本运行后大量报错403、405、404脚本录完能跑但一跑就大量报错。403通常是权限问题原因多为Cookie或token没做关联或者会话失效405则是请求方法不匹配可能是录制的脚本中请求方式如把POST录成了GET与实际接口要求不符404则是路径问题多半是录制时URL带了录制的环境绝对路径换环境后没调整或录到了开发环境独有的接口。处理思路是先看“查看结果树”里第一条报错的请求点开“请求体/响应体”对比录制时的请求和实际服务器期望的请求排查具体差异点。绝大多数403/405/404问题都能通过参数化、关联或调整端口/域名/路径解决。如果报错集中在某几个静态资源请求上直接删除它们即可——这些通常与核心业务无关。6.5 录制脚本乱码中文参数显示异常JMeter录制中文参数时偶尔会出现乱码比如用户名变成了%E5%BC%A0%E4%B8%89这样的编码串或者响应内容里中文全变成了问号。处理方式在JMeter的bin/jmeter.properties文件里找到sampleresult.default.encoding改为UTF-8。在HTTP请求里通过“参数”面板的“编码”列手动指定发送编码为UTF-8。如果响应乱码在“查看结果树”监听器的“结果”界面修改“编码”为UTF-8。编码问题其实不难但很多老手也会忽略因为不同项目的页面编码可能不同UTF-8和GBK录制时JMeter有时不能自动识别页面的原始编码。我的习惯是录制前就先确认目标系统是什么编码然后统一把jmeter.properties的默认编码改成对应值再开始录制能省去后续不少麻烦。7. 我的录制实操经验总结最后分享几个我实际用下来觉得非常有价值的细节。第一录制不是一次就能录好的。我现在的习惯是先录一遍“试录”不追求一次成功而是通过第一遍操作确认代理、证书、浏览器配置全部正常并且观察哪些请求录到了、哪些丢了。第二遍再正式录制这时候流程和节奏都已经熟悉录出来的脚本质量高很多。第二录制时控制操作节奏比操作内容更重要。我在一次录制中因为点击速度太快导致连续两个请求几乎同时发出JMeter把它们记录成了并发请求但实际业务上这两个请求有先后依赖关系结果脚本回放时一直报错。后来我把每步操作之间的间隔控制在2到3秒让请求在时间轴上清晰分隔脚本的稳定性大幅提升。如果你的业务操作本身很快可以在代理服务器配置中开启“Capture HTTP Request Headers”和请求延迟设置人为拉开请求间隔。第三脚本整理的时间投入不会低于录制本身。一个录制5分钟的业务流程清理静态资源、参数关联、加断言、调线程组通常需要半小时以上。这很正常不要指望录制一键生成可压测的脚本。把录制当作“快速搭架子”把整理当作“精装修”心态对了效率反而更高。第四关于HTTPS证书建议在团队内部做一次“标准配置文档沉淀”。因为每次新人入职我都会看到他们在证书导入这一步卡十分钟。把上面4.2节的操作步骤做成内部文档大家照着走能省不少事。录制脚本这件事往小了说是一个操作步骤往大了说是性能测试脚本开发效率的分水岭。掌握了录制和整理的完整链路你面对陌生Web业务流程时就不会怵因为再复杂的操作都可以先录下来再慢慢打磨成一条有效的压测脚本。如果你在某个环节卡住把报错信息贴到搜索引擎里基本都能找到解法——毕竟JMeter是老牌开源工具踩过这些坑的人不在少数。希望这篇实操经验能帮你少走几步弯路。