
1. 从“手动造轮子”到“自动录脚本”为什么我们需要录制功能做性能测试或者接口测试的朋友对JMeter这个工具肯定不陌生。我们经常需要模拟大量用户去访问一个Web应用或者调用一系列API接口。最开始你可能像我一样老老实实地在JMeter里手动添加HTTP请求采样器一个字段一个字段地填URL、请求方法、请求头、请求体。测一个简单的登录流程可能就得配三四个采样器还得处理Cookie、Session、动态参数比如CSRF Token。这活儿干一两次还行一旦遇到业务流程复杂、页面跳转多、接口参数繁琐的系统手动构建测试脚本就成了一个耗时费力、且极易出错的重体力劳动。这时候“录制脚本”这个功能的价值就凸显出来了。它本质上是一个“流量复制”或“行为录制”工具。你不需要再当“人肉翻译机”去把浏览器或客户端的行为手动翻译成JMeter的配置项。你只需要像正常用户一样在浏览器里操作一遍业务流程——点击这里输入那里提交表单——JMeter在后台默默地把你所有的网络请求HTTP/HTTPS都抓取下来并自动生成对应的测试脚本元件Sampler, Header, Cookie Manager等。这就像给测试过程装上了一台“录像机”你演一遍它全记下来了。我最初接触这个功能时觉得它简直是“神器”大大提升了脚本创建效率。但用多了就会发现直接录出来的脚本往往很“脏”包含大量无关请求如图片、CSS、JS等静态资源参数也可能是硬编码的无法直接用于压测。所以录制只是第一步更重要的是后续的“精修”和“参数化”。这篇内容我就结合自己这些年的踩坑经验把JMeter录制脚本的完整流程、核心配置、常见问题以及最重要的“后期处理心法”给你讲透。无论你是刚接触JMeter的新手还是想优化现有工作流的老手相信都能找到有用的东西。2. 录制原理与核心配置理解JMeter如何扮演“中间人”在开始动手之前我们得先搞明白JMeter是怎么把我们的操作“录”下来的。理解了原理后面配置和排错时你心里才有底。JMeter实现录制功能主要依靠一个叫“HTTP(S) Test Script Recorder”的元件。它的工作原理是典型的“代理服务器”模式。你可以把JMeter想象成一个“中间人”或者“网络哨卡”。工作流程是这样的你在JMeter中启动这个“录制器”Recorder它会在本机开启一个代理服务默认端口是8888。然后你需要配置你的浏览器或被测客户端告诉它“以后所有的网络流量都先发给JMeter代理localhost:8888再由JMeter帮你转发给真正的目标服务器。”当你通过这个配置好的浏览器去访问网站时请求会先到达JMeter。JMeter的录制器收到请求后会做两件事一是把这个请求的所有细节URL、方法、头、体等记录下来生成一个HTTP Request采样器二是将这个请求原封不动地转发给目标服务器。服务器返回的响应也会先经过JMeter代理再返回给你的浏览器。同时JMeter也可能记录下响应中的一些信息比如通过后置处理器提取动态值。这样你在浏览器里的所有操作就在JMeter里留下了一套完整的“剧本”。理解了原理我们来看最关键的配置。很多新手卡在第一步就是因为这里没配对。2.1 JMeter端的配置设置“哨卡”规则首先打开JMeter在“测试计划”上右键选择添加-非测试元件-HTTP(S) Test Script Recorder。这个元件的界面看似复杂但核心配置就几项端口默认8888。这就是“哨卡”的入口。只要不和你本机其他服务冲突用默认的就行。目标控制器这是决定“剧本”记在哪里的关键。我强烈建议你专门创建一个“录制控制器”。在测试计划下先右键添加一个逻辑控制器-录制控制器。然后在这个下拉框里选择你刚创建的“录制控制器”。这样所有录制的请求都会归到这个控制器下非常清晰便于后续管理。如果选“测试计划”请求会散落在根目录很乱。分组这个选项决定了如何组织录制的请求。对于现代Web应用单页应用或API测试我通常选择“每个组放入一个新的控制器”或“只存储每个组的第一个样本”。前者会把相同路径的请求归类后者则更精简。不要用默认的“不对样本分组”否则你会得到一长串毫无结构的请求列表后期整理会非常痛苦。包含模式和排除模式这是录制脚本的“过滤器”是保证脚本干净的核心你需要通过正则表达式来告诉JMeter哪些请求需要录哪些直接忽略。排除模式通常先把静态资源过滤掉。例如.*\.(js|css|PNG|jpg|png|gif|ico|woff|woff2).*。这个表达式可以过滤掉常见的JavaScript、样式表、图片、字体文件。这能极大减少无关请求。包含模式如果你只想录制特定域名的请求可以在这里设置。例如.*your-test-domain\.com.*。如果为空则录制所有通过代理的请求排除的除外。注意这里有个大坑。如果你的应用使用了WebSocket或非HTTP协议如gRPC标准的HTTP代理录制器是抓不到的。你需要寻找专门的插件或使用其他录制方案如Badboy、BlazeMeter Chrome扩展。配置好后先别急着点“启动”。我们还需要一个重要的东西CA证书。2.2 浏览器端的配置让流量经过“哨卡”因为JMeter要解密HTTPS流量否则它看不到请求内容它必须扮演一个“受信任的中间人”。为此JMeter会生成一个自签名的CA证书颁发机构证书。你的浏览器必须安装并信任这个证书否则访问HTTPS网站时会报安全错误。步骤通常是在JMeter的bin目录下找到ApacheJMeterTemporaryRootCA.crt文件如果第一次使用可能需要先启动一次录制器才会生成。将这个.crt文件导入到你的浏览器或系统的受信任根证书颁发机构存储中。不同浏览器导入方式不同一般在设置-隐私与安全-证书管理里。配置浏览器代理。你可以安装SwitchyOmega这类插件来方便地切换代理也可以直接在系统网络设置或浏览器设置里配置。代理服务器地址填127.0.0.1或localhost端口填JMeter里设置的默认8888。一个关键技巧我建议专门创建一个浏览器用户配置文件或者使用无痕/隐私模式并在这个模式下配置代理和安装证书。这样可以避免影响你正常的浏览也防止一些缓存的干扰。3. 实战录制流程从零开始抓取一个登录流程理论说再多不如动手做一遍。我们以一个最常见的“用户登录并查看主页”场景为例走通整个流程。3.1 环境准备与脚本结构搭建首先在JMeter里搭建一个清晰的脚本结构。一个好的结构是高效工作的基础。创建测试计划打开JMeter保存你的测试计划例如login_workflow.jmx。添加线程组右键测试计划 -添加-线程用户-线程组。这是我们所有测试逻辑的容器。可以先命名为“性能测试线程组”线程数保持1录制时我们只是单用户操作。添加录制控制器右键线程组 -添加-逻辑控制器-录制控制器。命名为“录制脚本存放处”。这是我们刚才在“目标控制器”里要选的那个。添加HTTP(S) Test Script Recorder右键“工作台”注意是左侧树形图最下面的“工作台”不是测试计划 -添加-非测试元件-HTTP(S) Test Script Recorder。配置录制器端口8888。目标控制器选择我们刚创建的“录制脚本存放处”。分组选择“每个组放入一个新的控制器”。排除模式添加.*\.(js|css|png|jpg|gif|ico|woff|woff2|svg).*。启动录制器点击界面下方的“启动”按钮。此时JMeter会在本机8888端口启动代理服务。3.2 浏览器配置与操作录制打开你配置好代理和CA证书的浏览器或隐私窗口。在地址栏访问你的目标网站例如https://example.com/login。像正常用户一样操作在登录页输入用户名、密码点击登录按钮。登录成功后可能跳转到主页你在主页上随意点击一两个链接。操作完成后回到JMeter点击录制器的“停止”按钮。此时你应该在“录制脚本存放处”这个录制控制器下看到JMeter自动生成了一系列的HTTP Request采样器并且很可能已经按路径或功能被分组到了不同的“事务控制器”里。同时JMeter会自动添加一个HTTP Cookie管理器到线程组级别用于管理会话。录制时的心得操作要干净录制时只进行你想要的业务流程操作。不要在同一浏览器标签页里做其他无关浏览以免录进垃圾请求。注意等待对于有前端渲染的页面点击后如果页面有加载动画或异步请求稍微等一下再进行下一步操作确保相关请求都被捕获。查看结果树录制过程中或录制后可以添加一个查看结果树监听器到线程组运行一下刚录制的脚本单线程看看每个请求的响应是否正常。这是初步验证脚本是否可用的好方法。4. 录后必做脚本清理、增强与参数化直接录制的脚本我们称之为“脏脚本”它离一个可用的、尤其是可压测的“健壮脚本”还有很大距离。接下来才是体现测试工程师功力的地方。4.1 清理无用请求首先利用“查看结果树”逐个检查录下来的请求。删除静态资源请求虽然我们设置了排除模式但可能仍有漏网之鱼比如一些动态生成的图片路径。确认是对业务逻辑无影响的静态资源请求直接删除。合并冗余请求有时候一个操作可能触发多个AJAX调用你需要判断哪些是核心的哪些是辅助的。对于查询类接口可能保留一个即可。关注重定向登录成功后的302重定向JMeter可能会录成两个独立的请求。你需要检查是否需要跟随重定向选项默认是勾选的或者是否要处理重定向后的请求。4.2 处理动态参数关键难点这是脚本能否成功回放的核心。现代Web应用充满了动态值录下来的脚本里这些值都是死的第二次运行就失效了。常见的有CSRF Token在表单或请求头中每次页面刷新都不同。ViewState某些框架如ASP.NET使用的状态保持令牌。会话ID可能体现在Cookie或URL路径中。时间戳、随机数用于防重放或缓存失效。处理方法是“先提取后引用”定位参数来源在“查看结果树”里找到登录页面的GET请求返回登录表单的那个请求。查看其响应数据搜索token、csrf等关键词找到这些动态值在响应体HTML、JSON中的位置。添加后置处理器提取在返回动态值的那个请求下右键添加后置处理器常用的是正则表达式提取器或JSON提取器。例如响应HTML中有一行input typehidden namecsrf_token valueabc123def456。使用正则表达式提取器引用名称填csrf_token正则表达式填namecsrf_token value(.?)模板填$1$匹配数字填1。在后续请求中引用在登录的POST请求中找到csrf_token这个参数将其值从录制的固定值abc123def456改为${csrf_token}。这样JMeter就会用提取到的动态值来替换。对于Cookie中的会话ID通常HTTP Cookie管理器会自动管理无需手动处理但要确保它被正确添加到了线程组级别。4.3 参数化与数据驱动为了模拟多个不同用户我们需要参数化。比如用户名和密码不能写死。准备数据文件创建一个CSV文件如users.csv包含username,password两列每行一对测试账号。添加CSV Data Set Config在线程组下添加配置元件-CSV Data Set Config。文件名指向你的users.csv。变量名称username,password与CSV列头对应。其他选项默认分隔符用逗号。替换脚本中的硬编码值将登录请求中的用户名和密码参数值分别改为${username}和${password}。这样在压测时每个虚拟用户线程迭代时都会从CSV文件中读取新的一行数据实现多用户登录。4.4 添加断言与监听器一个健壮的脚本必须有检查机制。断言在登录请求下添加响应断言检查响应数据中是否包含“登录成功”或用户名的关键字或者检查响应代码是否为200。这能帮你快速判断请求是否真的成功了。监听器调试时用查看结果树和调试取样器。正式压测时添加聚合报告、汇总报告、用表格查看结果等监听器来收集性能数据。切记监听器非常消耗资源在正式高并发压测时应禁用或仅保留必要的监听器最好将结果写入文件如使用“Simple Data Writer”后再分析。5. 进阶技巧与常见问题排坑掌握了基本流程再来看看那些容易踩坑的地方和提升效率的技巧。5.1 处理HTTPS证书问题除了之前提到的浏览器安装CA证书有时还会遇到“SSL握手失败”或“证书不匹配”错误这可能是因为目标服务器使用了JMeter不信任的证书如内部测试环境自签名证书。解决方法是在JMeter的HTTP请求采样器中勾选“从浏览器兼容性”选项它会忽略一些证书验证或者更规范的做法是将目标服务器的证书导入到JMeter的信任库。具体步骤是使用Java的keytool命令将.crt文件导入到JMeter使用的cacerts文件中。Android/iOS移动端APP录制原理相同需要在手机网络设置中配置代理服务器指向运行JMeter的电脑IP和8888端口并在手机上安装JMeter的CA证书将ApacheJMeterTemporaryRootCA.crt文件发送到手机并安装。注意Android高版本和iOS对证书安装有更严格的限制可能需要将证书安装到“受信任的凭据”中。5.2 录制控制器分组策略的深度选择之前提到了分组选项这里再深入一下“不对样本分组”最乱不推荐。“在组间添加分隔”只是加注释结构改善有限。“每个组放入一个新的控制器”最常用。它会根据请求的路径或模式自动创建“事务控制器”来分组请求。例如所有/api/login/**的请求会放到一个叫“Login”的控制器里。这非常利于后续管理和设置事务。“只存储每个组的第一个样本”适用于你明确知道同一组请求如轮询完全一样只需要一个样本代表的情况。可以极大精简脚本。“为每个组创建一个新的控制器并为每个请求添加前缀”和第三个类似但命名方式不同。我的习惯是先用“每个组放入一个新的控制器”录一遍得到一个有结构的脚本然后再手动调整和合并控制器。5.3 脚本模块化与重用当你需要测试一个包含多个模块的大系统时不要把所有操作都录在一个巨大的脚本里。按模块录制将登录、查询、下单等流程分别录制到不同的JMX文件中。使用“模块控制器”或“包含控制器”在主测试计划中使用逻辑控制器-模块控制器来调用这些独立的脚本模块。这样可以实现脚本的积木化拼装便于维护和复用。使用“用户自定义变量”将主机名、端口、协议等公共配置放在测试计划级别的用户自定义变量中在请求中使用${host}等方式引用。这样切换测试环境从测试到生产只需要改一个地方。5.4 性能测试脚本的特殊处理录制脚本用于功能测试回放可能问题不大但用于性能测试必须考虑更多思考时间录制时你的操作间隔是真实的人为延迟。在性能脚本中需要在请求之间添加定时器-固定定时器来模拟这个“思考时间”否则请求会毫无停顿地连续发送压力会不真实且可能远超实际场景。关联与参数化的彻底性确保所有动态参数都正确关联并且参数化数据足够多CSV文件行数要大于等于线程数*循环次数避免数据重复导致服务端缓存命中率异常高影响测试真实性。清理Cookies和缓存在线程组开始时可以添加一个HTTP Cookie管理器并设置为“每次迭代清除Cookies”或者添加一个HTTP请求采样器来访问一个清理会话的接口以确保每个虚拟用户会话独立。5.5 常见错误与排查录制不到任何请求检查浏览器代理配置是否正确IP和端口检查JMeter录制器是否已启动关闭防火墙或杀毒软件对JMeter和端口的拦截尝试用HTTP网站如http://httpbin.org测试排除HTTPS证书问题。脚本回放失败404/500首先用“查看结果树”对比录制和回放的请求。重点检查URL是否完整特别是包含动态参数的路径请求方法GET/POST是否正确请求头特别是Content-Type、User-Agent是否一致请求体数据是否一致且编码正确动态参数是否成功提取并替换。响应数据乱码在HTTP请求采样器中或HTTP请求默认值中设置内容编码如UTF-8。在监听器中也可以勾选“编码”选项。“Out of Memory”错误在jmeter.bat或jmeter.sh中调整JVM堆内存参数HEAP。对于大数据量或高并发的测试需要给予JMeter足够的内存。同时减少监听器的使用尤其是“查看结果树”不要保存过多数据。录制脚本是JMeter入门的捷径但它绝不是终点。它帮你快速搭建了脚本的骨架而肌肉和灵魂——逻辑校验、参数化、性能考量、稳定性增强——则需要你手动去填充和锤炼。把录制当作“采集原材料”把后续的清理、关联、参数化、断言当作“精加工”这样生产出来的测试脚本才是可靠、可维护、可重用的利器。我个人的习惯是即使时间再紧录完的脚本也至少要花录制时间一半以上的精力去优化和验证这个投入在后续的测试执行和问题排查中会加倍地回报给你。