ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

JMeter录制脚本全攻略:从原理到实战,打造高效性能测试脚本

JMeter录制脚本全攻略:从原理到实战,打造高效性能测试脚本

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想象成一个“中间人”或者“网络哨卡”。

工作流程是这样的:

  1. 你在JMeter中启动这个“录制器”(Recorder),它会在本机开启一个代理服务(默认端口是8888)。
  2. 然后,你需要配置你的浏览器(或被测客户端),告诉它:“以后所有的网络流量,都先发给JMeter代理(localhost:8888),再由JMeter帮你转发给真正的目标服务器。”
  3. 当你通过这个配置好的浏览器去访问网站时,请求会先到达JMeter。
  4. JMeter的录制器收到请求后,会做两件事:一是把这个请求的所有细节(URL、方法、头、体等)记录下来,生成一个HTTP Request采样器;二是将这个请求原封不动地转发给目标服务器。
  5. 服务器返回的响应,也会先经过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网站时会报安全错误。

步骤通常是:

  1. 在JMeter的bin目录下,找到ApacheJMeterTemporaryRootCA.crt文件(如果第一次使用,可能需要先启动一次录制器才会生成)。
  2. 将这个.crt文件导入到你的浏览器或系统的受信任根证书颁发机构存储中。不同浏览器导入方式不同,一般在设置->隐私与安全->证书管理里。
  3. 配置浏览器代理。你可以安装SwitchyOmega这类插件来方便地切换代理,也可以直接在系统网络设置或浏览器设置里配置。代理服务器地址填127.0.0.1localhost,端口填JMeter里设置的(默认8888)。

一个关键技巧:我建议专门创建一个浏览器用户配置文件,或者使用无痕/隐私模式,并在这个模式下配置代理和安装证书。这样可以避免影响你正常的浏览,也防止一些缓存的干扰。

3. 实战录制流程:从零开始抓取一个登录流程

理论说再多,不如动手做一遍。我们以一个最常见的“用户登录并查看主页”场景为例,走通整个流程。

3.1 环境准备与脚本结构搭建

首先,在JMeter里搭建一个清晰的脚本结构。一个好的结构是高效工作的基础。

  1. 创建测试计划:打开JMeter,保存你的测试计划,例如login_workflow.jmx
  2. 添加线程组:右键测试计划 ->添加->线程(用户)->线程组。这是我们所有测试逻辑的容器。可以先命名为“性能测试线程组”,线程数保持1(录制时我们只是单用户操作)。
  3. 添加录制控制器:右键线程组 ->添加->逻辑控制器->录制控制器。命名为“录制脚本存放处”。这是我们刚才在“目标控制器”里要选的那个。
  4. 添加HTTP(S) Test Script Recorder:右键“工作台”(注意,是左侧树形图最下面的“工作台”,不是测试计划!) ->添加->非测试元件->HTTP(S) Test Script Recorder
  5. 配置录制器
    • 端口:8888。
    • 目标控制器:选择我们刚创建的“录制脚本存放处”。
    • 分组:选择“每个组放入一个新的控制器”。
    • 排除模式:添加.*\.(js|css|png|jpg|gif|ico|woff|woff2|svg).*
  6. 启动录制器:点击界面下方的“启动”按钮。此时JMeter会在本机8888端口启动代理服务。

3.2 浏览器配置与操作录制

  1. 打开你配置好代理和CA证书的浏览器(或隐私窗口)。
  2. 在地址栏访问你的目标网站,例如https://example.com/login
  3. 像正常用户一样操作:在登录页输入用户名、密码,点击登录按钮。登录成功后,可能跳转到主页,你在主页上随意点击一两个链接。
  4. 操作完成后,回到JMeter,点击录制器的“停止”按钮。

此时,你应该在“录制脚本存放处”这个录制控制器下,看到JMeter自动生成了一系列的HTTP Request采样器,并且很可能已经按路径或功能被分组到了不同的“事务控制器”里。同时,JMeter会自动添加一个HTTP Cookie管理器到线程组级别,用于管理会话。

录制时的心得

  • 操作要干净:录制时,只进行你想要的业务流程操作。不要在同一浏览器标签页里做其他无关浏览,以免录进垃圾请求。
  • 注意等待:对于有前端渲染的页面,点击后如果页面有加载动画或异步请求,稍微等一下再进行下一步操作,确保相关请求都被捕获。
  • 查看结果树:录制过程中或录制后,可以添加一个查看结果树监听器到线程组,运行一下刚录制的脚本(单线程),看看每个请求的响应是否正常。这是初步验证脚本是否可用的好方法。

4. 录后必做:脚本清理、增强与参数化

直接录制的脚本我们称之为“脏脚本”,它离一个可用的、尤其是可压测的“健壮脚本”还有很大距离。接下来才是体现测试工程师功力的地方。

4.1 清理无用请求

首先,利用“查看结果树”,逐个检查录下来的请求。

  • 删除静态资源请求:虽然我们设置了排除模式,但可能仍有漏网之鱼(比如一些动态生成的图片路径)。确认是对业务逻辑无影响的静态资源请求,直接删除。
  • 合并冗余请求:有时候,一个操作可能触发多个AJAX调用,你需要判断哪些是核心的,哪些是辅助的。对于查询类接口,可能保留一个即可。
  • 关注重定向:登录成功后的302重定向,JMeter可能会录成两个独立的请求。你需要检查是否需要跟随重定向选项(默认是勾选的),或者是否要处理重定向后的请求。

4.2 处理动态参数(关键难点)

这是脚本能否成功回放的核心。现代Web应用充满了动态值,录下来的脚本里这些值都是死的,第二次运行就失效了。常见的有:

  • CSRF Token:在表单或请求头中,每次页面刷新都不同。
  • ViewState:某些框架(如ASP.NET)使用的状态保持令牌。
  • 会话ID:可能体现在Cookie或URL路径中。
  • 时间戳、随机数:用于防重放或缓存失效。

处理方法是“先提取,后引用”

  1. 定位参数来源:在“查看结果树”里,找到登录页面的GET请求(返回登录表单的那个请求)。查看其响应数据,搜索tokencsrf等关键词,找到这些动态值在响应体(HTML、JSON)中的位置。
  2. 添加后置处理器提取:在返回动态值的那个请求下,右键添加后置处理器,常用的是正则表达式提取器JSON提取器
    • 例如,响应HTML中有一行:<input type="hidden" name="csrf_token" value="abc123def456">
    • 使用正则表达式提取器:引用名称填csrf_token,正则表达式填name="csrf_token" value="(.+?)",模板填$1$,匹配数字填1
  3. 在后续请求中引用:在登录的POST请求中,找到csrf_token这个参数,将其值从录制的固定值abc123def456,改为${csrf_token}。这样,JMeter就会用提取到的动态值来替换。

对于Cookie中的会话ID,通常HTTP Cookie管理器会自动管理,无需手动处理,但要确保它被正确添加到了线程组级别。

4.3 参数化与数据驱动

为了模拟多个不同用户,我们需要参数化。比如,用户名和密码不能写死。

  1. 准备数据文件:创建一个CSV文件(如users.csv),包含username,password两列,每行一对测试账号。
  2. 添加CSV Data Set Config:在线程组下,添加配置元件->CSV Data Set Config
    • 文件名:指向你的users.csv
    • 变量名称:username,password(与CSV列头对应)。
    • 其他选项默认,分隔符用逗号。
  3. 替换脚本中的硬编码值:将登录请求中的用户名和密码参数值,分别改为${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-TypeUser-Agent)是否一致;请求体数据是否一致且编码正确;动态参数是否成功提取并替换。
  • 响应数据乱码:在HTTP请求采样器中,或HTTP请求默认值中,设置内容编码(如UTF-8)。在监听器中也可以勾选“编码”选项。
  • “Out of Memory”错误:在jmeter.batjmeter.sh中调整JVM堆内存参数(HEAP)。对于大数据量或高并发的测试,需要给予JMeter足够的内存。同时,减少监听器的使用,尤其是“查看结果树”不要保存过多数据。

录制脚本是JMeter入门的捷径,但它绝不是终点。它帮你快速搭建了脚本的骨架,而肌肉和灵魂——逻辑校验、参数化、性能考量、稳定性增强——则需要你手动去填充和锤炼。把录制当作“采集原材料”,把后续的清理、关联、参数化、断言当作“精加工”,这样生产出来的测试脚本才是可靠、可维护、可重用的利器。我个人的习惯是,即使时间再紧,录完的脚本也至少要花录制时间一半以上的精力去优化和验证,这个投入在后续的测试执行和问题排查中,会加倍地回报给你。

返回列表