资讯动态

性能测试实战指南:LoadRunner 2022 R1 脚本开发与压测分析全流程

发布时间:2026/10/20 8:19:02 来源:尧图企业网站定制
做性能测试绕不开 LoadRunner 这个名字。即使现在开源压测工具已经非常成熟LoadRunner 2022 R1 在很多商业项目里依然是默认选择它把脚本录制、压力生成、资源监控、结果分析串成了一条完整链路适合那些需要明确指标、可复现、好归档的场景。我用它做过接口级脚本也拿它做过整链路压测。这篇文章把最核心的概念和实操拆开讲VuGen 怎么写脚本、Controller 怎么加压、Analysis 怎么读结果以及我踩过的坑。无论你是刚接触性能测试还是从 JMeter 切到 LoadRunner都可以照着这套流程走一遍。1. 先搞清楚性能测试到底在解决什么问题1.1 性能测试不只是“压一压看看崩不崩”很多人第一次接触性能测试脑子里就一句话“用工具发起很多请求看服务器扛不扛得住。”这句话没错但不够完整。性能测试的目标通常分几类负载测试关心系统在预期业务量下响应时间是否达标压力测试关心系统超过预期负载后表现如何比如是否快速失败、恢复能力怎样容量测试则是在做规划时回答“最多能支撑多少用户”稳定性测试更关注长时间运行下是否有内存泄漏、连接池耗尽等慢慢暴露的问题。举个例子某个业务系统每天早上 9 点会迎来一波用户集中登录。如果你只做功能测试你看到的是“一个人登录很快”但只验证了正确性。性能测试要回答的是当同时有 5000 个人在 5 分钟内登录登录页会不会变成“龟速”数据库连接池会不会被耗尽应用服务器会不会假死。我习惯用一个生活类比功能测试是看“一个人过收费站能不能顺利通过”性能测试是看“五一假期最后一天收费站每个车道都排满车时队排多长、通过率多高、哪个窗口先顶不住”。LoadRunner 就是那个帮你安排车流并发、记录每辆车耗时的工具。1.2 LoadRunner 2022 R1 的四大组件是怎么分工的很多新手拿到 LoadRunner 2022 R1第一反应是“图标这么多入口到底在哪里”。其实你只需要记住四个角色VuGen、Controller、Analysis 和 Load Generator。VuGen 负责“做脚本”。你录制或者手写脚本定义用户会做什么操作、每一步怎么发请求、要不要做参数化、要不要关联动态数据。脚本做完之后才算有了一个可复用的“虚拟用户”。Controller 负责“组织并发”。你在 Controller 里决定启动多少个虚拟用户、花多长时间加载、持续跑多久、怎么停止。它还负责连接 Load Generator 机器把脚本分发到一台或多台机器上执行。Load Generator 是真正“干活”的机器。Controller 只做调度压力是从 Load Generator 发出去的。这意味着你的压测机不是只有一台电脑而是可以横向扩展到多台机器避免“压测工具这边先撑不住”。Analysis 负责“出结果”。压力跑完后Analysis 会生成摘要、事务响应时间、TPS、吞吐量等图表。真正有价值的分析往往不是第一眼看到的“平均响应时间”而是曲线变化趋势、错误分布、资源使用率之间的关联。1.3 为什么有些团队还在用 LoadRunner做技术选型时总有人问JMeter 免费LoadRunner 要授权为什么还要用它我的看法是LoadRunner 的价值不在某个单一功能上而在于整套流程的成熟度。它提供的协议录制、脚本回放、参数化、关联、场景调度、资源监控是成体系的而且对团队协作更友好。比如需求方要看“每秒事务数是多少”你不需要和开发讨论脚本里哪个 sampler 对应哪个事务直接在 Analysis 里导一份报告就行。LoadRunner 2022 R1 的 VuGen 是 64 位版本大脚本回放更稳定录制和回放过程中的报错信息也更接近业务语言方便定位是脚本问题还是服务端问题。如果你的团队预算充足而且被测对象是复杂的企业级系统用它做基线测试和准入测试是省心的选择。当然如果团队完全自研、预算有限JMeter 完全够用性能测试的核心思路两边是通用的。2. VueGen 脚本开发不只是“录一下就能跑”2.1 录脚本前先把协议和录制模式选对很多初学者在 VuGen 里新建脚本时直接点“Record”结果录完发现脚本全是空请求或者回放时到处报错。第一个最容易踩的坑就是协议选错。LoadRunner 录制脚本的原理是监听客户端和服务器之间的通信把请求“翻译”成脚本函数。对于绝大多数 Web 系统选择 HTTP/HTML 协议就够了。如果被测对象是移动端 App 后端接口或者系统里有 WebService你需要根据实际通信方式选择 WebService、TLS 或者 Socket 等协议。选择协议后还有一个隐藏选项Recording Options 里可以选择“HTML-based Script”还是“URL-based Script”。HTML-based 录出来的是偏用户行为的脚本比如web_url、web_submit_data可读性强适合页面性业务流程。URL-based 录出来的是每个底层请求脚本会更碎但适合客户端请求包含大量 Ajax、自定义 Header 或者需要精确控制请求顺序的场景。我个人的建议是做业务压测优先用 HTML-based它生成的脚本更容易做参数化和关联做接口性能测试直接手写脚本或者用 URL-based别依赖录制。2.2 录出第一条“干净”的脚本然后加事务录制脚本时要养成一个习惯把业务步骤控制在一条完整链路上。比如登录、查询订单、提交订单这是一个有价值的用户操作链路不要从打开首页到退出登录都录进去脚本太长不好维护也容易引入无关噪音。录完脚本后VuGen 会把脚本放在 vuser_init、Action、vuser_end 三个区段里。vuser_init 通常存放登录等初始化操作每个虚拟用户只会执行一次Action 是迭代执行的段真正压测时反复运行的就是这部分vuser_end 放退出、清理操作。最要紧的是给关键业务加事务。没有事务标记的脚本LoadRunner 只知道“请求成功”不知道“登录耗时多少”“提交订单耗时多少”。你需要圈出业务起点和终点像这样Action() { lr_start_transaction(登录); web_url(登录页, URLhttp://测试服务器/login, Resource0, RecContentTypetext/html, LAST); web_submit_data(登录提交, Actionhttp://测试服务器/login, MethodPOST, RecContentTypetext/html, ItemDataNameusername, Value{username}, ENDITEM, ItemDataNamepassword, Value{password}, ENDITEM, LAST); lr_end_transaction(登录, LR_AUTO); lr_start_transaction(查询订单); // 中间省略查询请求 lr_end_transaction(查询订单, LR_AUTO); return 0; }需要注意的一点事务名不能重名嵌套顺序要小心。如果你在登录事务还没结束时又开始了下一个事务那么前一个事务的耗时统计就会包含后一段逻辑数据会失真。还有不要把lr_start_transaction放在 vuser_init 里因为 init 只跑一次它统计不了迭代场景下的业务波动。2.3 参数化别让一千个虚拟用户共用同一个账号功能测试里一个账号反反复复登录没问题性能测试不行。真实用户注册了不同账号服务端为了鉴权、防重、数据隔离往往对同一账号的并发操作有限制。如果你不参数化一百个虚拟用户用同一个账号并发登录可能压出来的“响应慢”其实是被锁账号导致的。参数化操作不复杂。在脚本里选中要替换的字符串右键选择“替换为新参数”然后在参数属性里配置数据来源。常见做法是准备一个 CSV 文件里面放用户名和密码数据参数名分别为 username、password脚本里用{username}、{password}引用。真正容易出错的是下面两个设置“选择下一行”和“更新值的时间”。设置项可选值使用场景Select next rowSequential / Random / Unique决定每个虚拟用户每轮迭代取的是哪一行数据Update value onEach occurrence / Each iteration / Once决定同一个 Vuser 在多少次请求内更新参数值举个例子登录语句里用了 username 参数如果设置成 Sequential Each iteration那么第一个 Vuser 第一次迭代取第一行第二次迭代取第二行第二个 Vuser 第一次迭代也取第一行。如果希望每个 Vuser 各自锁定一个账号则要设置成 Unique Once再设置迭代次数不超过数据行数。最稳妥的测试方式是让每个用户的请求路径和数据彼此隔离。你可以为每个 Vuser 准备独立的参数集比如用户编号段测试结束后导出日志时也方便回溯“是哪个用户的数据出了问题”。这样后续定位服务端问题会省很多时间。2.4 关联处理服务器动态返回的核心技术录制脚本最大的问题不是“录不下来”而是“录下来了但回放失败”。常见原因是服务器每次返回的动态值不一样比如登录返回的 sessionId、下单返回的订单号、页面里隐藏的 token。这些动态值在录制时被写死到了脚本里回放时服务器发现值不匹配直接拒绝请求。解决办法是关联先从服务器返回值里把动态值抓出来再在后续请求中替换成这个动态值。LoadRunner 有自动关联功能但我不建议你完全依赖它。自动关联经常会抓到一堆没用的动态数据而且有的动态数据是经过 JS 计算的自动识别未必准确。手写关联的核心是找边界。比如服务器返回内容里有sessionId:abc123为了抓到 abc123可以在请求前用web_reg_save_paramweb_reg_save_param(sessionId, LBsessionId\:\, RB\, SearchBody, NOTFOUNDwarning, LAST); web_url(获取会话, URLhttp://测试服务器/api/session, Resource0, LAST); // 后续请求携带该动态值 web_add_header(X-Session-Id, {sessionId}); web_url(查询订单, URLhttp://测试服务器/order/list, Resource0, LAST);关联函数有个特点它必须在真正的请求之前注册因为 LoadRunner 是先用这个函数去“预登记”一个捕获逻辑再在后续请求返回时提取数据。很多新手把它放在请求后面结果永远抓不到。另外边界字符串里的双引号是转义字符的重灾区。你可以先把服务器返回的内容粘贴出来数清楚左右边界要尽量短但又不能歧义。边界越长越精确但服务器一改格式你的脚本就废了边界太短则容易抓到错误数据。2.5 思考时间压测数字像不像真实用户它很关键真实用户不会像机器一样一秒不差地连续点击。页面加载完人总要停顿一下、看一眼、输入点什么。这个间隔就是思考时间。录制时 LoadRunner 会自动生成lr_think_time默认回放时会按录制的延迟执行。场景里要不要保留思考时间取决于你的压测目的。做容量估算时保留合理的思考时间能模拟真实业务压力做接口最大吞吐测试时通常要去掉思考时间看系统在不喘气的情况下的极限。我见过不少团队为了追求“压得更狠”把所有 think time 都删掉结果压出来的吞吐量虚高上线后又达不到这个数据。适当保留思考时间反而更接近生产观测。你可以给lr_think_time设置一个随机范围比如 2 到 5 秒模拟真实用户的行为波动。随机范围比固定值更接近实际情况也能减少多个虚拟用户同时“同步点击”造成的压力尖峰。3. Controller 场景设计从脚本到压力的关键一跳3.1 场景类型怎么选普通并发还是目标导向脚本做好以后进入 Controller 新建场景。LoadRunner 2022 R1 里常见的有两种场景玩法手动场景和基于目标的场景。手动场景适合调查型测试。你明确地设置并发用户数、加载时间和运行时长比如“100 个用户1 分钟加载完持续 15 分钟”。这种玩法能给你一个确定性的负载形态方便对比不同版本的表现。基于目标的场景适合验收型测试。你在场景里设置一个目标值比如“每秒事务数要达到 50”LoadRunner 会逐步增加虚拟用户数直到达标或者系统到达瓶颈。如果你的需求就是“支撑每秒 100 笔订单”这种场景能给团队一个直观结论。从实践来看不要一上来就直奔高强度压力。我会先跑一遍单用户脚本确认脚本本身没有报错、思考时间设置合理再用小并发比如 5 个用户跑一遍观察基础数据最后才按梯度往上加。3.2 用户加载方式一次性铺开是新手最常见的暴力操作场景设计中加载策略比并发数本身更容易被忽略。很多测试计划写成“启动 200 个用户”执行时直接 200 个并发同时冲进来。真实业务不是这样的用户是在一个时间段内陆续到达的。LoadRunner 里可以把加载过程分成多段比如前 5 分钟每秒增加 5 个用户保持 20 分钟再让压力自然下降。这样做有两个好处一是给系统一个预热过程JIT 编译、缓存填充、连接池初始化都需要时间二是你能在渐增的过程中观察响应时间从哪个用户数开始劣化相比之下比较容易定位拐点。持续时间也不是越长越好。压测时长取决于业务场景做稳定性测试我会让系统在 70% 到 80% 目标负载下持续跑几个小时甚至一夜做短时压力测试30 分钟以内也能看出问题。关键是场景停止时要设计“软着陆”不要让 200 个用户在同一秒全部断开否则服务端可能把断连误判成故障日志里全是连接重置。3.3 资源监控别等系统挂了才发现问题只盯着事务响应时间看是远远不够的。响应时间上升可能是应用服务器 CPU 打满也可能是数据库慢查询还可能是带宽挤满。你需要在压测进行时同步监控服务器资源。Windows 环境监控常见计数器Processor 的 % Processor Time、Memory 的 Available MBytes、PhysicalDisk 的 % Disk Time。Linux 环境 LoadRunner 支持 Unix Resources 监控但依赖 rstatd 服务。很多 Linux 发行版默认没安装 rstatd连接不上时不要慌先在目标机器上确认 rpcbind 和 rstatd 是否正常。容器化和云主机环境下监控手段会更多样。比如直接在命令侧用top、vmstat、dstat记录现场甚至从云平台拉监控曲线。无论用哪种方式压测现场留下的监控数据必须和 LoadRunner 的分析结果能对上时间轴否则分析阶段就没有依据了。4. Analysis 结果分析从一堆图表里找线索4.1 拿到报告先看哪几个指标压测结束Analysis 会自动打开结果会话。新手容易一下子扎进几十个图表里其实第一步应该看摘要。摘要页里要优先确认三件事第一事务总数和成功数是否符合预期第二平均响应时间是否达标第三错误率有没有异常。如果错误率不是 0先去看错误日志搞清楚是脚本参数问题还是服务端返回 4xx/5xx。错误没有定位之前后面的平均值都有误导性。还要注意“平均响应时间”这个指标的局限。如果 99% 的请求都是 10 毫秒1% 的请求是 10 秒平均值会把问题掩盖掉。所以实际分析中要多看响应时间的分布、90 分位、95 分位而不是只有一个平均值就下结论。4.2 四张图表组合起来读我比较常用的组合是平均事务响应时间、每秒事务数TPS、吞吐量和 HTTP 响应分类。平均事务响应时间曲线看业务体验变化TPS 曲线看系统处理能力是否随用户增长而增长吞吐量曲线看数据流量趋势可以对照带宽是否成为瓶颈HTTP 响应分类能直观看到 200、404、500、超时请求的数量。读图时不要只看最后一段要看整体的变化过程。正常系统在压力渐增时TPS 会跟着涨响应时间会缓慢增加当系统饱和后TPS 不再增加甚至下降响应时间快速上升此时对应的用户数就是系统的实际容量拐点。再结合 CPU、内存、磁盘等资源曲线基本能判断瓶颈出在哪一层。4.3 典型曲线形态什么情况算“异常”一种形态是 TPS 一直平、响应时间也不涨到了某个用户数突然大面积报错。这种情况常见于网关限流、连接数限制或者数据库连接池打满。另一种形态是用户数还在增加但 TPS 不再涨响应时间快速恶化。这种情况多半是服务端已经到了处理上限比如单实例 CPU 打满加用户也不再提高吞吐量反而因为排队拖慢已有请求。还有一种形态是压测期间整体表现不错但运行一段时间后 TPS 逐步下降。这往往暗示内存泄漏、临时文件堆积、连接池没有释放等问题。遇到这种形态一定要把压测时长拉长观察几个完整周期不能只跑 5 分钟就收工。5. LoadRunner 2022 R1 实操中容易踩的坑5.1 录出来是空脚本回放也没有请求这个问题我在帮同事排查时遇到过好几次。原因通常是协议选择不正确或浏览器走了系统代理以外的通道。LoadRunner 录制时会在本机启动一个代理端口浏览器必须走到这个代理上才会被抓到请求。如果是 HTTPS 站点还有证书问题。录制时会弹证书信任提示没有正确信任的话请求也可能抓不全。我的排查顺序是先看录制时浏览器能否正常打开页面再检查录制选项里的代理和端口最后看协议列表。更保险的做法是不依赖自动录制直接用捕获的接口文档手写脚本。很多业务系统尤其是接口型项目录制反而是绕了一大圈。5.2 参数化“更新策略”选错导致隐性失败脚本回放时登录成功压测跑起来却大量报认证失败。排查脚本时发现参数值都取到了但用户数据已经被前面的迭代用掉。比如你要模拟 100 个用户各登录一次参数设置成“Sequential Each occurrence”前面 50 个 Vuser 可能把 50 行数据用掉了后面的 Vuser 取到重复数据被服务端踢掉。改成“Unique Once”后问题立刻消失。参数化数据量也要留有余量。如果并发用户是 100数据行却只准备了 60 行那么剩余用户的取值就会出现“用尽”或“循环”进而导致压出的结果含杂质。准备数据时要考虑整个测试时长内所有迭代的总消耗量不要只看单次脚本。5.3 Linux 资源监控连不上这个坑很典型。Controller 里添加 Unix Resources 监控目标机开启 rstatd 后依然连不上。很多云主机的安全组默认屏蔽了相关 RPC 端口或者在系统层面没有安装完整的 rpcbind 套件。我在实践中的做法是不把资源监控全部押在 LoadRunner 的一个功能上。压测的同时用dstat在目标机上直接记录日志或者让运维从监控平台导出 CPU、内存、磁盘、网络曲线。LoadRunner 的监控图表适合做统一报告但现场数据备份更重要二者对得上时间轴就行。5.4 压测跑到一半脚本全部失败先分清是脚本还是系统压力一高大量报错出现时第一反应往往是“系统崩了”。但别忘了先看错误信息的归属。如果错误是“连接超时”“SSL 握手失败”可能是服务端过载或负载生成机与服务端之间的网络带宽被占满。如果错误是“响应内容未找到”“关联动态值未捕获”很可能是脚本中的动态处理不够健壮压力大了之后页面中的 token 或 session 获取失败。遇到大批量失败我会在场景里临时打开更详细的日志截取一条失败请求的完整服务端响应再判断。千万不要在没定位错误码的时候贸然重跑场景那样只是重复烧机器时间。5.5 容易被忽略的场景级配置有几个配置项对新手很有迷惑性。比如集合点脚本里写了lr_rendezvous但如果在 Controller 里没有启用集合点设置它不会真正同步等待。集合点的作用是把大量虚拟用户集中在同一个操作上发起压力适合模拟秒杀、整点开抢这类场景。默认不启用时每个用户跑到那里就自己往下走了。还有迭代次数与脚本结构的关系。如果我们希望压测模拟的是用户反复下单那 Action 部分要能够安全重复执行如果脚本里有很多随业务变化的动态数据重复迭代时要注意会不会因为上一次执行留下了状态导致后续请求失败。建议 Action 保持“无状态”设计每次迭代都能独立跑通。6. 完整工作流与个人习惯建议6.1 从需求到报告一条可复用的流程我推荐新手把性能测试拆成固定几个阶段前一个阶段的产出是后一个阶段的输入。第一步是明确指标比如目标 TPS、响应时间上限、错误率上限、并发用户数范围。第二步是录制和开发脚本至少要包含一个主链路和一个次链路。第三步是参数化与关联确保脚本回放稳定。第四步是在 Controller 里设计小并发冒烟场景跑通后逐梯度加压。第五步是执行正式场景同时记录目标机资源。第六步是导出 Analysis 报告并整理成结论瓶颈在哪、系统是否达到目标、建议是什么。这套流程看起来简单但每一条都做到位不容易。很多人跳过第二步直接上来压最后只会得到一堆看似华丽但无法解释的数字。6.2 设计用例前先把这七个问题问清楚做性能测试最怕的是需求没对齐就开跑。接到任务时我会先和业务方确认预期的峰值用户量是多少这个峰值是每天出现一次还是持续一段时间核心业务路径是哪几条响应时间达标线是多少是平均值还是 95 分位测试环境的数据量和生产环境差多少客户端网络条件是内网还是互联网允许的最大错误率是多少这些问题直接影响场景设计和数据分析。比如目标环境网络延迟很高你测出来响应时间偏长不代表业务系统慢可能是客户端链路本身的问题。如果数据量只有生产的百分之一数据库查询表现会远好于生产直接外推很容易误判。6.3 我的一点实践体会最后分享一个工作习惯每次压测跑完我会把场景文件、脚本压缩包、Analysis 原始结果和现场监控日志一起归档。下一次优化后要复现同样规模的测试直接打开原始结果对比就能看出差异在哪不需要靠“我记得上次状态挺好”这种模糊记忆。LoadRunner 2022 R1 这套工具并不复杂复杂的是你对业务的理解、对数据的判断和对瓶颈的定位能力。先把基础工作流跑顺再慢慢积累自己的经验库性能测试这条路就能越走越稳。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑