LoadRunner性能测试实战指南
简介:LoadRunner是IT行业中广泛使用的高性能负载与压力测试工具,能够模拟大量并发用户,检测系统在高负载下的稳定性与性能表现。本资料涵盖LoadRunner核心组件VUGen、Controller和Analysis的使用方法,介绍基于C语言风格的VuGen脚本编写、多协议支持、测试场景设计及分布式测试实现。通过实际操作演练,帮助测试人员掌握从脚本录制、场景配置到结果分析的完整流程,提升软件性能测试能力,为系统优化提供数据支撑。
1. LoadRunner简介与应用场景
LoadRunner核心架构与组件解析
LoadRunner由三大核心组件构成: Virtual User Generator(VuGen) 、 Controller 和 Analysis 。VuGen负责录制和开发模拟用户行为的测试脚本,支持多种协议如HTTP/HTML、Web Services、JDBC等;Controller用于设计负载场景并控制虚拟用户并发执行;Analysis则对测试结果进行聚合分析,生成响应时间、吞吐量、资源利用率等关键性能指标图表。各组件协同工作,实现从脚本创建到压力施加再到数据洞察的完整闭环。
graph TD
A[VuGen] -->|生成脚本| B(Controller)
B -->|运行场景| C[被测系统]
C -->|产生性能数据| D(Analysis)
D -->|输出报告| E[性能瓶颈诊断与优化建议]
该架构支持本地及分布式负载生成,可模拟成千上万用户同时访问系统,广泛应用于金融交易系统、电商平台大促压测、电信计费平台等高可用性要求场景。
2. VUGen虚拟用户生成器使用与脚本录制
2.1 VUGen工作界面与核心功能解析
2.1.1 脚本创建向导与协议选择策略
在LoadRunner Professional或Enterprise版本中,Virtual User Generator(VuGen)是构建性能测试脚本的核心工具。其主要作用是通过模拟真实用户的操作行为,生成可执行的虚拟用户(Virtual User, VUser)脚本,进而用于后续的负载测试场景设计。启动VuGen后,系统默认进入“新建脚本”向导界面,该界面提供了多种协议类型供选择,正确选择协议是确保后续脚本能够成功回放和准确反映业务逻辑的关键。
协议的选择直接影响到脚本录制的方式、底层通信机制以及参数化与关联处理的技术路径。常见的协议包括:
- HTTP/HTML :适用于基于浏览器的Web应用,支持GET/POST请求、Cookie管理、动态资源加载等。
- Web Services (SOAP/REST) :用于调用基于XML或JSON格式的API接口,适合前后端分离架构。
- Citrix / Terminal Emulator :针对老旧C/S架构系统,如银行柜面系统。
- Java Vuser :适用于Java RMI调用或嵌入式Java客户端应用。
- Oracle NCA / SAP GUI :专用于企业ERP系统的自动化测试。
选择协议时需结合被测系统的实际技术栈进行判断。例如,若目标系统为现代单页应用(SPA),前端通过AJAX频繁调用RESTful API,则应优先选用 Web Services 或 HTTP/HTML 协议,并开启高级选项中的“Generate non-HTML resources”以捕获所有异步请求。
以下是一个典型的协议选择决策流程图(Mermaid格式):
graph TD
A[确定被测系统类型] --> B{是否为Web应用?}
B -->|是| C{是否包含大量异步API调用?}
B -->|否| D[选择专用协议: Citrix/SAP等]
C -->|是| E[选择HTTP/HTML + 启用资源捕获]
C -->|否| F[选择HTTP/HTML基础模式]
G[存在独立WebService接口?] --> H[添加Web Service协议]
当多个协议并存时,VuGen支持多协议脚本(Multi-Protocol Script),允许在一个脚本中组合不同协议的操作步骤,从而更真实地模拟复合型业务流。
参数说明与最佳实践
| 协议类型 | 适用场景 | 录制粒度 | 是否支持自动关联 |
|---|---|---|---|
| HTTP/HTML | Web页面、AJAX应用 | 高 | 是 |
| Web Services | 接口级服务调用 | 中 | 手动配置 |
| JDBC | 直接数据库操作 | 细 | 否 |
| Flex/Tuxedo | 企业级中间件通信 | 粗 | 需定制 |
建议在项目初期进行 协议探测测试 :先以HTTP/HTML协议录制简单登录流程,观察日志中是否存在大量JSON/XML响应体;如有,则进一步启用“Correlation Studio”进行智能关联分析,提升脚本稳定性。
2.1.2 录制模式对比:基于浏览器与基于WinInet的区别
VuGen提供两种主要的录制引擎: 基于浏览器的录制(Browser-based Recording) 和 基于WinInet的录制(WinInet-based Recording) 。两者在底层实现、兼容性及调试能力上存在显著差异,合理选择可大幅减少后期脚本调整成本。
基于浏览器的录制(Browser-based Recording)
此模式依赖真实的浏览器实例(通常为IE或Chrome扩展)来驱动用户操作。VuGen通过插件注入方式监听HTTP(S)流量,捕获DOM事件与网络请求,尤其适用于JavaScript密集型应用(如React/Vue构建的SPA)。
优点:
- 能完整记录由JS动态生成的URL和参数;
- 支持HTTPS解密(需安装LoadRunner根证书);
- 可视化操作体验接近真实用户。
缺点:
- 对浏览器版本敏感,易出现兼容性问题;
- 不支持非浏览器类应用(如桌面程序);
- 启动慢,资源消耗大。
配置路径: Tools > Options > Recording > Record > Use browser for recording
基于WinInet的录制(WinInet-based Recording)
该模式绕过浏览器,直接通过Windows Internet API(WinInet.dll)截获应用程序发出的HTTP请求。常用于C/S结构软件或轻量级Web客户端。
优点:
- 录制速度快,系统开销小;
- 更贴近底层协议交互,便于分析请求头细节;
- 支持非GUI程序录制。
缺点:
- 无法识别JavaScript生成的内容;
- 对重定向、Session机制处理较弱;
- 难以应对复杂的前端框架路由。
典型应用场景举例:某金融交易客户端采用.NET开发,通过内嵌Web控件访问后台API。此时使用WinInet模式可精准捕捉其发出的所有POST请求,而基于浏览器的方式可能因控件隔离导致漏录。
混合模式的应用趋势
随着微前端架构普及,越来越多的企业开始采用“混合录制策略”——即先用浏览器模式完成UI层操作录制,再手动补全WinInet层级的安全认证请求(如OAuth2 Token获取)。这种分层录制方法既保证了覆盖率,又提升了脚本可控性。
下面是一个比较表格,帮助团队根据实际情况做出决策:
| 特性 | 基于浏览器录制 | 基于WinInet录制 |
|---|---|---|
| 兼容性 | 仅限指定浏览器 | 广泛适用于Win32应用 |
| JS动态内容捕获能力 | 强 | 弱 |
| HTTPS支持 | 是(需证书配置) | 是 |
| 请求还原准确性 | 高 | 中 |
| 调试便利性 | 图形化,易于理解 | 文本为主,需专业知识 |
| 推荐使用场景 | 现代Web应用、移动端H5 | 传统C/S系统、API直连 |
⚠️ 注意事项:无论哪种模式,在首次启用HTTPS录制前,必须将LoadRunner CA证书导入操作系统受信任根证书库,否则将无法解密SSL流量,导致关键参数丢失。
2.1.3 Action、Init、End三个阶段的作用与执行逻辑
VuGen脚本遵循标准的三段式结构: vuser_init 、 Action 、 vuser_end 。这不仅是组织代码的良好习惯,更是影响性能测试结果准确性的关键因素。每个部分承担不同的职责,其执行频率和上下文环境也各不相同。
阶段定义与执行顺序
// 示例脚本结构
vuser_init()
{
lr_start_transaction("Login_Init");
web_set_sockets_option("SSL_VERSION", "AUTO");
web_add_auto_header("User-Agent", "Mozilla/5.0...");
web_reg_find("Text=Welcome", LAST);
web_submit_data("login",
"Action=https://app.example.com/login",
"Method=POST",
ITEMDATA,
"Name=username", "Value={user}", ENDITEM,
"Name=password", "Value={pwd}", ENDITEM,
LAST);
lr_end_transaction("Login_Init", LR_AUTO);
return 0;
}
Action()
{
lr_start_transaction("Search_Order");
web_url("search",
"URL=https://app.example.com/order?uid={user_id}",
"Resource=0",
"RecContentType=text/html",
LAST);
// 提取订单号用于后续操作
web_reg_save_param_ex(
"ParamName=ORDER_ID",
"LB=\"orderId\":\"",
"RB=\"}",
"SEARCH_FILTERS",
"Scope=Body",
LAST);
lr_end_transaction("Search_Order", LR_AUTO);
return 0;
}
vuser_end()
{
web_submit_data("logout",
"Action=https://app.example.com/logout",
"Method=GET",
LAST);
return 0;
}
vuser_init() 初始化阶段
- 执行时机 :每个虚拟用户启动时仅执行一次。
- 用途 :
- 登录认证(获取Session/Cookie)
- 设置运行时选项(Think Time、超时时间)
- 加载参数文件(CSV、Excel)
- 建立数据库连接(适用于DB Vuser)
- 注意事项 :
- 不宜放入高频事务,避免初始化耗时过长影响加压节奏;
- 若在此阶段失败,整个VUser将标记为“Failed to Initialize”。
Action() 主体执行阶段
- 执行时机 :根据场景设置重复执行多次(Iteration)。
- 用途 :
- 核心业务流程模拟(查询、下单、支付等)
- 事务划分与性能度量
- 参数化与关联逻辑集中处理
- 优化建议 :
- 使用
lr_start_transaction()和lr_end_transaction()明确界定事务边界; - 利用
web_reg_find()添加检查点,验证响应正确性; - 控制每轮迭代时间,避免过短造成压力失真。
vuser_end() 结束清理阶段
- 执行时机 :虚拟用户退出前执行一次。
- 用途 :
- 注销会话(logout)
- 关闭连接池
- 数据清理(删除临时记录)
- 重要提示 :
- 此阶段不计入性能指标统计(如TPS、响应时间);
- 忽略该阶段可能导致服务器Session堆积,影响长期稳定性测试。
执行生命周期示意图(Mermaid流程图)
sequenceDiagram
participant Controller
participant VuGen
Controller->>VuGen: 启动VUser
VuGen->>VuGen: 执行vuser_init()
alt 初始化失败
VuGen-->>Controller: 报告错误,终止
else 成功
loop 执行N次Action
VuGen->>VuGen: 执行Action()一次
end
VuGen->>VuGen: 执行vuser_end()
VuGen-->>Controller: 完成测试
end
从性能工程角度看,合理的阶段划分有助于实现“一次登录,多次操作”的真实用户行为建模。例如在电商秒杀测试中, vuser_init 负责抢购资格预热(登录+缓存预加载), Action 模拟点击“立即购买”, vuser_end 释放库存锁或取消未支付订单,形成闭环。
此外,LoadRunner还支持自定义额外Action块(Insert > New Action),可用于模块化组织复杂流程。例如将“购物车管理”、“订单提交”、“支付确认”分别封装为独立Action,提升脚本复用率与维护效率。
2.2 脚本录制技术实践
2.2.1 HTTP/HTML协议下的网页操作录制流程
HTTP/HTML协议是最广泛使用的录制协议之一,特别适用于传统的B/S架构系统。其录制过程本质上是对浏览器发起的HTTP请求链的镜像捕获。以下是完整的操作流程及关键配置点。
步骤一:配置录制选项
打开VuGen → File → New Script → Choose Protocol → HTTP/HTML
进入录制设置面板后,需重点配置以下几项:
| 设置项 | 推荐值 | 说明 |
|---|---|---|
| Recording Level | Advanced (Replay think time) | 显示完整函数调用 |
| Browse the following URL | https://target-app.example.com | 指定起始页 |
| HTML-based script | Selected | 推荐选中 |
| URL-based script | Not selected | 除非特殊需求 |
勾选“Record within current application context”可限制只录制目标域名下的请求,避免第三方资源干扰。
步骤二:启动录制并执行业务操作
点击“Start Recording”按钮,VuGen将自动打开默认浏览器并导航至指定URL。此时可像普通用户一样进行如下操作:
- 输入用户名密码并登录;
- 浏览商品列表;
- 添加商品至购物车;
- 提交订单。
在整个过程中,VuGen会在后台持续记录每一个HTTP请求,包括GET、POST、PUT等方法,并自动识别表单字段、隐藏参数、Cookies等信息。
步骤三:停止录制并生成脚本
完成操作后点击工具栏“Stop”按钮,VuGen进入脚本编辑界面。此时会看到类似以下结构的代码:
web_url("index.html",
"URL=https://app.example.com/index.html",
"TargetFrame=",
"Resource=0",
"RecContentType=text/html",
LAST);
web_submit_form("login",
"Snapshot=t1.inf",
ITEMDATA,
"Name=username", "Value=admin", ENDITEM,
"Name=password", "Value=123456", ENDITEM,
LAST);
其中:
- web_url() 表示导航到某个页面;
- web_submit_form() 表示提交表单数据;
- "Snapshot=t1.inf" 是录制期间保存的页面快照,用于调试比对;
- LAST 是参数列表结束符,不可省略。
逻辑分析与参数说明
上述脚本中每一行都对应一次HTTP交互。以 web_submit_form 为例:
| 参数名 | 含义说明 |
|---|---|
| Name/Value | 表单字段名与值,支持硬编码或参数化变量(如 {username} ) |
| Snapshot | 指向录制时刻的页面状态文件,辅助定位元素位置 |
| ITEMDATA…ENDITEM | 标识一组键值对输入项 |
| LAST | 表示当前函数参数列表结束 |
💡 提示:若发现某些Ajax请求未被捕获,可在Recording Options中启用“Record and generate steps for async requests (AJAX)”选项。
最终生成的脚本应能独立回放并通过检查点验证,这是进入下一阶段(参数化与关联)的前提。
2.2.2 参数化输入字段以实现动态请求模拟
静态脚本只能模拟单一用户行为,无法体现真实并发场景下的多样性。因此必须对关键输入字段进行 参数化 (Parameterization),使每次迭代使用不同的数据集。
参数化实现方式
VuGen提供三种主要参数化机制:
- CSV文件驱动
- 内部参数生成器(Random, Counter, Date等)
- 数据库查询结果绑定
以用户登录为例,原始脚本为:
web_submit_data("login",
"Action=https://app.example.com/auth",
"Method=POST",
ITEMDATA,
"Name=uname", "Value=admin", ENDITEM,
"Name=pwd", "Value=pass123", ENDITEM,
LAST);
将其改为参数化形式:
web_submit_data("login",
"Action=https://app.example.com/auth",
"Method=POST",
ITEMDATA,
"Name=uname", "Value={username}", ENDITEM,
"Name=pwd", "Value={password}", ENDITEM,
LAST);
其中 {username} 和 {password} 是参数占位符。
创建参数文件(CSV)
右键选中“username” → Replace with Parameter → Create New Parameter
命名参数为 user_credentials ,类型选择 File,然后编辑CSV内容如下:
username,password
testuser1,Pass@123
testuser2,Pass@456
testuser3,Pass@789
在Run-time Settings中设置:
- Select next row: Sequential
- When exhaust data: Abort Vuser
这样每个VUser按顺序读取一行数据,实现多账户并发登录。
参数控制策略对比表
| 策略 | 适用场景 | 并发安全性 |
|---|---|---|
| Sequential | 基准测试、数据唯一性要求高 | 高 |
| Random | 模拟随机行为 | 中 |
| Unique + Block | 大规模注册类测试 | 高 |
🔐 安全提醒:敏感数据(如密码)应加密存储或使用外部凭证管理系统集成。
参数化不仅提升真实性,还能暴露因缓存共享、会话冲突引发的问题,是性能测试不可或缺的一环。
2.2.3 关联机制应用:提取服务器返回动态值并重用
许多Web应用在每次请求后会返回唯一的会话令牌(如JSESSIONID、CSRF Token、Transaction ID),这些值必须在后续请求中正确传递,否则服务器将拒绝处理。这就是所谓的 动态关联 (Correlation)问题。
手动关联示例
假设服务器在登录成功后返回如下HTML片段:
<input type="hidden" name="csrf_token" value="abc123xyz">
需要提取该值并在提交订单时使用。
步骤如下:
-
在响应中查找左边界(LB)和右边界(RB):
- LB:name="csrf_token" value="
- RB:" -
插入
web_reg_save_param_ex函数:
web_reg_save_param_ex(
"ParamName=CSRF_TOKEN",
"LB=name=\"csrf_token\" value=\"",
"RB=\"",
"SEARCH_FILTERS",
"Scope=Body",
LAST);
web_submit_data("login",
...
LAST);
// 后续请求中引用
web_submit_data("submit_order",
"Action=https://app.example.com/order",
ITEMDATA,
"Name=token", "Value={CSRF_TOKEN}", ENDITEM,
LAST);
函数参数详解
| 参数名 | 说明 |
|---|---|
| ParamName | 存储提取值的变量名 |
| LB / RB | 左右边界字符串,支持文本或正则 |
| Scope | 搜索范围(Body、Headers、All) |
| SEARCH_FILTERS | 可附加过滤条件,如仅搜索特定URL |
自动关联配置(Smart Correlation)
对于复杂系统(如Salesforce、SharePoint),手动关联成本过高。此时可启用VuGen内置的 Smart Correlation 功能:
路径: Tools > Correlation Studio
选择规则集(Rule Set)→ 扫描脚本 → 自动生成候选关联 → 应用推荐方案
系统会基于历史经验库识别常见模式(如ViewState、EventValidation),极大提升效率。
关联有效性验证流程图
graph LR
A[录制原始脚本] --> B[回放失败?]
B -->|是| C[查看日志定位缺失Token]
C --> D[添加web_reg_save_param_ex]
D --> E[重新回放验证]
E -->|成功| F[完成关联]
E -->|失败| G[调整LB/RB或作用域]
G --> D
成功的关联意味着脚本能稳定回放至少10次以上且无403/401错误,这是进入Controller运行大规模负载的前提条件。
2.3 常见录制问题与解决方案
2.3.1 会话ID丢失导致回放失败的调试方法
会话ID(Session ID)是维持用户状态的核心标识,常见形式有JSESSIONID(Java)、PHPSESSID(PHP)、ASP.NET_SessionId等。若VuGen未能正确捕获并重用该值,会导致服务器认为每次请求来自新用户,从而中断业务流程。
故障现象
- 回放时报错:“Invalid session”、“Login required”
- 日志显示Cookie header为空或旧值
- 事务响应时间异常偏高(频繁重定向到登录页)
解决方案
- 启用自动Cookie处理
在Runtime Settings → Internet Protocol → Preferences中:
- 勾选“Handle multiple IP addresses”(若启用了IP欺骗)
- 设置“Automatic correlation”为On
- 确保“Use concurrent groups”未启用(除非明确需要)
- 手动捕获Set-Cookie头
若自动机制失效,可通过 web_reg_save_param 捕获响应头中的Session ID:
web_reg_save_param("JSESSIONID",
"LB=Set-Cookie: JSESSIONID=",
"RB=;",
"Scope=Headers",
LAST);
web_url("home", "URL=https://app.example.com/", LAST);
然后在后续请求中显式设置:
web_add_cookie("JSESSIONID={JSESSIONID}; DOMAIN=example.com");
- 验证Cookie传递完整性
使用 lr_debug_message(LR_MSG_CLASS_ALL_MESSAGES, "ON"); 开启详细日志,检查每一步是否携带正确的Cookie。
排查清单表
| 检查项 | 是否通过 | 备注 |
|---|---|---|
| 录制时已登录? | ✅ / ❌ | |
| 是否启用自动Cookie管理? | ✅ / ❌ | |
| Set-Cookie头是否出现在响应中? | ✅ / ❌ | |
| Cookie是否跨Action传递? | ✅ / ❌ | |
| SSL证书是否信任? | ✅ / ❌ | 影响安全通道建立 |
坚持按此流程排查,90%以上的会话问题均可解决。
2.3.2 验证码或时间戳处理技巧
验证码(CAPTCHA)和时间戳(Timestamp)是阻碍自动化测试的两大障碍。它们的设计初衷正是为了防止机器人行为,但在性能测试中需设法绕过。
时间戳处理
多数API为防重放攻击会在请求中加入时间戳参数,如:
https://api.example.com/data?ts=1712345678&t=abc123
其中 ts 为当前Unix时间, t 为签名。
解决方法:
long current_ts = time(NULL);
lr_save_datetime("%Y%m%d%H%M%S", DATE_NOW); // 格式化时间
lr_save_int(current_ts, "timestamp");
web_custom_request("get_data",
"URL=https://api.example.com/data?ts={timestamp}&t={signature}",
...
LAST);
签名(signature)若为固定算法(如MD5(secret + ts)),可用 lr_eval_string 结合外部DLL计算。
验证码规避策略
-
测试环境禁用验证码
- 最佳方案:联系开发团队在测试环境中关闭验证码校验
- 配置开关:captcha.enabled=false -
使用通用验证码
- 如系统接受“1234”作为合法值,可在参数文件中统一填写 -
OCR识别(极端情况)
- 使用第三方图像识别库(如Tesseract)+ LoadRunner DLL扩展
- 成本高,仅用于无法修改代码的遗留系统
⚠️ 法律与伦理提示:生产环境不得绕过安全机制,所有操作应在授权范围内进行。
2.3.3 多步事务中同步点设置与页面等待策略
复杂业务往往涉及多个异步步骤(如支付→通知→回调),若不加以控制,脚本可能在页面未加载完成时就发送下一条请求,导致失败。
同步点设置方法
- 使用
web_reg_find等待关键文本出现
web_reg_find("Text=Payment Confirmed", "SaveCount=PAY_FOUND", LAST);
web_url("check_status", "URL=https://app.example.com/status", LAST);
if (atoi(lr_eval_string("{PAY_FOUND}")) == 0) {
lr_think_time(5); // 等待5秒重试
}
- 设定最长等待时间(Timeout)
在Runtime Settings → Pacing中设置:
- Maximum wait time for a response: 30 seconds
- Connect timeout: 10 seconds
- 结合JavaScript执行状态判断(TruClient专属)
对于高级脚本,可使用 web_sync 或 web_wait_for_element 确保DOM元素可见后再继续。
页面等待策略对比
| 方法 | 精确性 | 实现难度 | 适用协议 |
|---|---|---|---|
| Think Time固定延迟 | 低 | 简单 | 所有 |
| web_reg_find检查文本 | 中 | 中等 | HTTP/HTML |
| DOM元素等待 | 高 | 高 | TruClient Only |
| Polling轮询接口 | 高 | 中 | REST/WebSocket |
推荐组合使用“动态等待 + 最大超时”,既能提高成功率,又能防止无限挂起。
综上所述,掌握VuGen的各项核心功能与调试技巧,是构建高质量性能测试脚本的基础。只有深入理解每个组件的工作原理,才能在面对复杂系统时游刃有余,确保测试结果的真实可信。
3. VuGen脚本语言(LR-VuGen)基础与编辑技巧
LoadRunner 的虚拟用户生成器(VuGen)不仅是一个录制工具,更是一个功能完整的脚本开发环境。其核心编程语言称为 LR-VuGen,基于 C 语言语法并扩展了大量专用于性能测试的函数库和运行时机制。掌握 LR-VuGen 不仅意味着能够回放简单的操作流程,更重要的是具备对复杂业务逻辑进行建模、参数化、关联处理以及错误控制的能力。对于拥有五年以上经验的 IT 测试工程师或 DevOps 工程师而言,深入理解 LR-VuGen 的语法结构与高级编辑技巧是实现高效、可维护、高仿真度性能测试脚本的关键。
在现代微服务架构中,单一事务往往涉及多个动态接口调用、身份认证令牌传递、异步响应等待等复杂行为。传统的“录制-回放”模式已无法满足需求,必须依赖手动编码增强脚本来应对这些挑战。因此,本章将从底层语言特性出发,系统剖析 LR-VuGen 的编程模型,并结合实际场景讲解如何通过脚本优化提升测试的真实性与稳定性。
3.1 LR-VuGen语法结构与编程模型
LR-VuGen 继承了 ANSI C 的基本语法规范,但在运行环境、内存管理及函数调用方式上做了大量定制化改造,以适应多线程并发执行虚拟用户的行为模拟。它不是标准 C 编译器所能直接编译的语言,而是由 LoadRunner 自有的解释引擎解析执行。这种设计使得 LR-VuGen 能够无缝集成 VuGen 的运行时数据交换机制、参数服务器通信、日志记录系统等功能。
3.1.1 函数库分类:运行时函数、字符串处理、日志输出
LoadRunner 提供了丰富的内置函数库,按照用途可分为以下几类:
| 类别 | 主要函数示例 | 功能说明 |
|---|---|---|
| 运行时控制 | lr_start_transaction() , lr_end_transaction() | 控制事务边界,用于统计响应时间 |
| 字符串处理 | lr_eval_string() , lr_save_string() | 参数替换与变量保存 |
| 日志与调试 | lr_output_message() , lr_log_message() | 输出调试信息到回放日志 |
| Web 请求 | web_url() , web_submit_data() | 发起 HTTP 请求 |
| 数据参数化 | lr_paramarr_len() , lr_next_row() | 操作参数化数组和数据表 |
| 关联提取 | web_reg_save_param_ex() , web_create_html_param() | 提取服务器返回的动态值 |
其中,最常用的三大类别为 运行时函数 、 字符串处理函数 和 日志输出函数 。它们构成了脚本编写的基础支撑体系。
例如,在一个典型的登录流程中,需要先发起请求获取会话 token,再将其作为后续请求的头部参数发送。这就需要用到 web_reg_save_param_ex 来捕获 token 值,并通过 lr_eval_string 在后续请求中动态引用该参数:
// 注册正则表达式来提取 JWT Token
web_reg_save_param_ex(
"ParamName=authToken",
"LB=\"token\":\"",
"RB=\"",
SEARCH_FILTERS,
"Scope=Body",
LAST);
// 发起登录请求
web_submit_data("login",
"Action=https://api.example.com/v1/auth/login",
"Method=POST",
"RecContentType=application/json",
"Referer=",
"Snapshot=t1.inf",
ITEMDATA,
"Name=username", "Value={username}", ENDITEM,
"Name=password", "Value={password}", ENDITEM,
LAST);
// 使用提取到的 token 发送受保护资源请求
web_add_header("Authorization", "Bearer {authToken}");
web_url("get_profile",
"URL=https://api.example.com/v1/user/profile",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t2.inf",
LAST);
代码逻辑逐行分析:
- 第 2–6 行:使用
web_reg_save_param_ex设置动态值提取规则。“LB”表示左边界,“RB”表示右边界,即在响应体中查找"token":"<value>"并提取<value>部分。- 第 9–17 行:提交登录表单,其中
{username}和{password}是参数化字段,来源于外部数据文件或随机生成器。- 第 20 行:利用
web_add_header添加 Authorization 头部,{authToken}是前一步自动填充的变量。- 第 23–28 行:访问用户资料页,此时携带有效 Token,完成完整链路验证。
此过程体现了 LR-VuGen 如何通过函数组合实现动态交互。值得注意的是,所有参数替换均发生在运行时,而非编译期,这保证了每个虚拟用户都能独立持有自己的上下文状态。
此外,日志输出在调试阶段至关重要。推荐使用 lr_output_message 输出关键变量值:
lr_output_message("当前用户: %s, 提取的Token: %s", lr_eval_string("{username}"), lr_eval_string("{authToken}"));
参数说明:
%s是格式化占位符,对应字符串类型;lr_eval_string()用于解析包含参数的字符串,确保{username}被替换成真实值后再打印;- 输出内容将出现在 VuGen 回放日志窗口中,便于排查空值或关联失败问题。
3.1.2 变量作用域与参数类型(常量、参数、变量)管理
在 LR-VuGen 中,存在三种主要的数据载体: 常量 、 参数 和 变量 ,它们的作用域和生命周期各不相同。
数据类型对比表
| 类型 | 示例 | 存储位置 | 生命周期 | 是否支持动态替换 |
|---|---|---|---|---|
| 常量 | "https://example.com" | 栈空间 | 单次迭代内有效 | 否 |
| 参数 | {user_id} | 参数服务器 | 全局共享,可跨Action | 是 |
| 变量 | char* sessionKey; | 局部栈或堆 | 当前线程/事务内有效 | 否(除非显式赋值) |
- 常量 :硬编码文本,适用于不变的 URL 或固定字段;
- 参数 :大括号包裹的标识符,如
{product_code},背后绑定一个参数化数据源(CSV 文件、数据库查询结果、随机数生成器等),每次调用自动更新; - 变量 :使用标准 C 语法声明的局部变量,可用于临时存储中间结果,但需注意线程安全问题。
// 声明局部字符数组变量
char orderId[64];
// 从响应中提取订单ID并存入变量
web_reg_save_param("orderId",
"LB=\"order_id\":\"",
"RB=\"",
"Search=All",
LAST);
web_url("create_order",
"URL=https://api.example.com/v1/order",
"Method=GET",
LAST);
// 将参数值复制给C变量(注意缓冲区溢出风险)
strcpy(orderId, lr_eval_string("{orderId}"));
// 构造下一步请求路径
char url[128];
sprintf(url, "https://api.example.com/v1/order/%s/status", orderId);
web_url("check_status",
"URL={url}",
"Method=GET",
LAST);
逻辑分析:
- 此脚本演示了如何将关联提取的结果从参数
{orderId}转移到本地 C 变量orderId,以便参与字符串拼接;sprintf构造新的 URL 路径,最后仍可通过{url}参数形式注入请求(假设已使用lr_save_string(url, "url")保存);- 必须警惕缓冲区溢出问题,建议使用
snprintf替代sprintf。
作用域图解(Mermaid 流程图)
graph TD
A[脚本全局] --> B[Init Action]
A --> C[Action]
A --> D[End Action]
B --> E[参数定义<br>{user}, {pwd}]
C --> F[局部变量<br>char temp[50];]
D --> G[释放资源]
style A fill:#f9f,stroke:#333
style E fill:#bbf,stroke:#000,stroke-width:1px
style F fill:#dfd,stroke:#000,stroke-width:1px
图中显示:
- 所有 Actions 共享同一组参数空间;
- 局部变量仅在所属 Action 内可见;
- Init 通常用于初始化连接或加载参数,End 用于清理资源。
这种设计允许不同 Action 模块间共享上下文(如登录态 token),同时避免变量命名冲突。
3.1.3 控制流语句在复杂场景中的应用(if-else、for循环)
尽管 LR-VuGen 支持完整的 C 控制流语法,但在性能测试中应谨慎使用,以免引入不必要的复杂性影响测试效率。
条件判断:if-else 分支选择
int statusCode = atoi(lr_eval_string("{http_status}"));
if (statusCode == 200) {
lr_output_message("请求成功,继续执行...");
lr_start_transaction("Process_Valid_Response");
// 执行后续操作
web_url("next_step", ...);
lr_end_transaction("Process_Valid_Response", LR_PASS);
} else if (statusCode >= 400) {
lr_log_message(LOG_ERROR, "HTTP 错误码: %d", statusCode);
lr_end_transaction("Main_Transaction", LR_FAIL);
return -1; // 终止当前虚拟用户
}
参数说明:
atoi()将字符串参数转换为整数;LOG_ERROR级别日志将被高亮显示,有助于快速定位异常;return -1可终止当前 VUser 执行,防止无效操作浪费资源。
循环结构:for 循环批量操作
int i;
int itemCount = lr_paramarr_len("productId"); // 获取 productId 数组长度
for (i = 0; i < itemCount; i++) {
lr_save_int(i + 1, "currentIndex"); // 记录当前索引
lr_output_message("正在处理第 %d 个商品", i + 1);
web_submit_data("add_to_cart",
"Action=https://shop.example.com/cart/add",
ITEMDATA,
"Name=pid", "Value={productId_{currentIndex}}", ENDITEM,
LAST);
lr_think_time(2); // 模拟用户思考时间
}
逻辑分析:
lr_paramarr_len("productId")返回参数数组元素个数(前提是 productId_1, productId_2… 存在);- 使用
{productId_{currentIndex}}实现嵌套参数引用,动态切换商品 ID;lr_think_time(2)插入 2 秒延迟,增强行为真实性。
这类结构非常适合模拟“浏览多个商品加入购物车”的用户行为路径。
综上所述,LR-VuGen 虽然语法简洁,但通过合理运用函数库、参数机制与控制流语句,可以构建出高度仿真的复杂测试场景。下一节将进一步探讨脚本增强技巧,包括正则关联、自定义函数封装等内容,进一步提升脚本质量与可维护性。
4. Controller控制器场景设计与负载模型配置
在企业级性能测试实践中,LoadRunner的Controller模块是实现负载调度、场景执行与资源监控的核心枢纽。它不仅承担着将VuGen中开发完成的虚拟用户脚本转化为真实并发压力的关键任务,还通过灵活的场景配置机制支持多种测试策略,满足从功能验证到极限压测的不同需求层次。一个科学合理的场景设计能够准确反映生产环境中的用户行为模式,并为后续性能瓶颈分析提供可靠的数据支撑。因此,深入掌握Controller的运行逻辑、负载生成机制以及实时监控集成方法,对于构建高保真度的性能测试体系至关重要。
4.1 场景规划与测试目标设定
有效的性能测试始于清晰的目标定义和周密的场景规划。Controller作为负载编排的中枢平台,其首要任务是根据业务需求建立可量化的测试目标,并据此制定详细的负载模型。这包括确定虚拟用户的规模、加压方式、持续时间及预期达成的性能指标(SLA),从而确保测试过程具备方向性和可评估性。
4.1.1 确定并发用户数、加压方式与时长
并发用户数的设定并非盲目追求高数值,而应基于系统的历史访问数据或预估的峰值流量进行建模。例如,在电商平台的大促活动中,可以通过日志分析工具统计每秒请求数(RPS)并反推所需模拟的虚拟用户数量。LoadRunner允许以“每秒启动N个VU”或“阶梯式递增”等方式逐步施加压力,避免因瞬时激增导致网络拥塞或服务崩溃。
加压策略的选择直接影响测试结果的真实性。常见的加压方式包括:
- 立即加压 :所有虚拟用户在同一时刻启动,适用于短时高峰场景。
- 渐进式加压 :按固定间隔分批启动用户,更贴近自然增长的用户流量。
- 波浪式加压 :周期性地增加与减少负载,用于检测系统在波动压力下的恢复能力。
测试时长需覆盖系统的冷启动、稳定运行与资源释放全过程。通常建议至少维持15分钟以上的稳态负载,以便观察系统是否出现内存泄漏或连接池耗尽等问题。
| 加压方式 | 适用场景 | 配置参数示例 |
|---|---|---|
| 立即启动 | 登录认证突发请求 | 启动延迟=0s,用户数=500 |
| 阶梯递增 | 容量边界探测 | 每3分钟增加100 VU,共5阶 |
| 波浪循环 | 节假日流量波动模拟 | 周期=10min,峰谷差=200 VU |
graph TD
A[开始测试] --> B{选择加压模式}
B -->|立即启动| C[全部VU同时初始化]
B -->|渐进式| D[按时间片分批激活]
B -->|波浪式| E[周期性升降负载]
C --> F[执行脚本]
D --> F
E --> F
F --> G[收集性能数据]
G --> H[生成报告]
该流程图展示了不同加压策略在Controller中的控制路径。无论采用哪种方式,关键在于保证负载变化的可控性和可观测性,使测试过程具有复现价值。
4.1.2 区分基准测试、容量测试与稳定性测试目标
不同的测试类型对应不同的性能验证目的,必须在Controller中明确区分其场景配置逻辑。
基准测试 (Baseline Testing)旨在获取系统在标准条件下的性能表现,作为未来优化前后的对比基线。此时应使用单一脚本、固定用户数(如50 VU)、关闭Think Time以排除干扰因素,重点记录响应时间、吞吐量等核心指标。
容量测试 (Capacity Testing)用于探索系统最大承载能力。可通过逐步提升并发用户数直至错误率超过阈值(如>1%)或响应时间显著恶化来识别拐点。在此类场景中,推荐启用自动停止规则,当连续多次迭代失败率达到设定上限时终止测试,防止无效消耗资源。
稳定性测试 (Soak Testing)关注长时间运行下的系统健康状况。典型配置为保持中等负载(如80%预估容量)持续运行数小时甚至数天,监测CPU、内存、数据库连接等资源是否存在缓慢上升趋势。此类测试常暴露GC频繁、连接未释放等隐蔽问题。
以下是一个典型的多阶段测试方案配置表:
| 测试类型 | 并发用户数 | 持续时间 | Think Time | 监控重点 |
|---|---|---|---|---|
| 基准测试 | 50 | 10分钟 | 关闭 | 响应时间均值、TPS |
| 容量测试 | 100→1000 | 动态调整 | 开启 | 错误率、系统拐点 |
| 稳定性测试 | 600 | 4小时 | 开启 | 内存增长、线程堆积 |
通过合理组合这些测试目标,可以在Controller中构建完整的性能验证闭环。
4.1.3 制定SLA标准并与业务需求对齐
服务等级协议(SLA)是连接技术指标与业务诉求的桥梁。在Controller中配置场景时,必须将抽象的用户体验要求转化为具体的量化阈值。例如:
- “首页加载应在2秒内完成” → 设置事务
Home_Page_Load的平均响应时间 ≤ 2000ms; - “下单成功率不低于99.9%” → 允许错误率 ≤ 0.1%;
- “系统支持每分钟处理1万笔订单” → TPS ≥ 167。
这些SLA规则可在Controller的“Scenario Schedule”中设置为 Goal-Oriented Scenario 的目标约束,系统将自动调整负载以逼近目标值,极大提升了测试效率。
此外,还需考虑非功能性需求的影响。例如金融系统可能要求全天候可用性,需在夜间低峰期执行压力测试;而电商系统则需在大促前一周集中开展全链路压测,确保各环节协同无误。
综上所述,场景规划不仅是技术操作,更是业务理解与工程实践的融合过程。只有将用户行为、系统架构与商业目标有机结合,才能在Controller中构建出真正有价值的性能测试场景。
4.2 负载生成策略配置
Controller的负载生成能力决定了性能测试的真实性和有效性。通过精细化配置用户组、执行策略与思考时间参数,可以最大限度还原生产环境中的复杂交互行为。
4.2.1 手动场景 vs 目标导向场景的选择依据
LoadRunner提供了两种主要的场景模式: Manual Scenario 和 Goal-Oriented Scenario ,二者适用于不同的测试目的。
Manual Scenario 允许测试人员完全手动控制虚拟用户的分布、加压节奏与执行逻辑,适合需要精确控制变量的调试型测试。例如,在排查某个特定接口的性能瓶颈时,可单独运行该脚本并固定并发数,便于隔离干扰。
Goal-Oriented Scenario 则以预设性能目标为导向,由Controller自动调节负载以达成指定指标,如“达到100 TPS”或“维持响应时间低于1.5秒”。这种模式特别适用于容量规划和自动化回归测试。
| 特性 | Manual Scenario | Goal-Oriented Scenario |
|---|---|---|
| 控制粒度 | 高 | 中 |
| 自动化程度 | 低 | 高 |
| 适用阶段 | 调试、专项测试 | 回归、容量评估 |
| 是否支持多目标 | 否 | 是(最多5个目标) |
| 是否依赖历史数据 | 否 | 是(需前期基准测试支持) |
选择依据主要取决于测试成熟度。初期可先用Manual模式建立基线,后期过渡到Goal-Oriented实现高效验证。
4.2.2 用户组分配与多脚本协同执行控制
现代应用往往涉及多个子系统协同工作,因此在Controller中常需配置多个用户组(User Groups)来模拟不同类型的角色行为。例如在一个银行系统中:
- 普通客户组 :执行查询余额、转账等轻量操作;
- 柜员组 :调用后台审批流程,涉及复杂事务;
- 管理员组 :批量导入数据,产生高IO负载。
每个用户组可绑定不同的VuGen脚本,并独立设置并发数、调度策略与地理分布(若使用远程负载发生器)。通过“Percentage Mode”还可按比例分配总负载,如客户占70%,柜员占25%,管理员占5%。
// 示例:在脚本中标识用户角色(用于日志追踪)
lr_set_transaction("Transfer_Money", START);
web_submit_data("doTransfer",
"Action=https://bank.example.com/transfer",
"Method=POST",
"RecContentType=text/html",
"Referer=https://bank.example.com/main",
"Snapshot=t1.inf",
ITEMDATA,
"Name=fromAccount", "Value={AccountNum}", ENDITEM,
"Name=toAccount", "Value=987654321", ENDITEM,
"Name=amount", "Value={TransferAmount}", ENDITEM,
LAST);
lr_set_transaction("Transfer_Money", END, LR_AUTO);
代码逻辑逐行解读:
-
lr_set_transaction("Transfer_Money", START);—— 标记事务开始,用于统计该操作的响应时间; -
web_submit_data()—— 发送POST请求模拟转账动作; - 参数
{AccountNum}和{TransferAmount}为参数化变量,分别来自数据池或随机生成; -
LAST表示参数列表结束; -
lr_set_transaction(..., END, LR_AUTO);—— 结束事务并自动提交结果至Controller。
此类多脚本协作场景下,Controller会统一聚合各组性能数据,便于横向比较不同业务流的表现差异。
4.2.3 思考时间(Think Time)调整对真实性的优化
思考时间是指虚拟用户在两个操作之间暂停的时间,用以模拟人类用户的阅读、输入等延迟。默认情况下,VuGen录制的脚本包含实际操作间隔,但在回放时可通过“Run-time Settings”进行调控。
Controller提供三种Think Time模式:
- Use original recorded think time :保留原始间隔,最接近真实行为;
- Multiply recorded think time by a factor :按比例缩放,便于加速或减速测试节奏;
- Ignore think time completely :去除所有等待,用于极限压力测试。
合理设置Think Time有助于平衡测试效率与真实性。例如在稳定性测试中,保留正常Think Time(如2-5秒)更能暴露缓存失效、会话超时等问题;而在性能拐点探测中,可暂时关闭Think Time以快速逼近系统极限。
此外,还可通过 lr_think_time(seconds) 函数在脚本中插入动态等待:
// 插入3秒随机浮动的思考时间
double rand_delay = 3.0 + ((double)rand() / RAND_MAX) * 2.0;
lr_think_time(rand_delay);
此段代码引入了±1秒的随机扰动,增强行为多样性,防止所有VU同步操作造成“雷鸣效应”。
4.3 运行时设置与监控集成
4.3.1 迭代次数、超时设置与异常处理策略
在Controller的“Run-time Settings”中,必须精细配置脚本执行的行为边界。关键参数包括:
- Maximum number of iterations :控制每个VU执行脚本的轮次;
- Duration :设定场景总运行时间;
- Timeout settings :包括连接超时(Connect Timeout)、接收超时(Receive Timeout)等;
- Error handling :定义遇到HTTP 5xx或网络异常时的应对策略(继续/停止/重试)。
例如,为防止个别请求卡死影响整体进度,可设置:
Connect Timeout: 30 seconds
Receive Timeout: 60 seconds
Pacing: After each iteration, wait 2 seconds
同时启用“Continue on error”选项,确保即使部分请求失败,其余用户仍能继续施压,从而完整采集系统降级过程中的性能退化曲线。
4.3.2 实时监控服务器资源指标(CPU、内存、I/O)
Controller支持通过Agent或无代理方式接入被测服务器的操作系统级监控。常用指标包括:
| 指标类别 | 监控项 | 采样频率 | 异常阈值参考 |
|---|---|---|---|
| CPU | %Processor Time | 10s | >85% |
| 内存 | Available MBytes | 10s | <500MB |
| 磁盘 | Disk Queue Length | 15s | >2 |
| 网络 | Bytes Total/sec | 10s | 接近带宽上限 |
通过添加“Add Measurements”功能,可将Windows Performance Counter或Linux sar数据实时展现在Graph视图中,形成“请求-资源”联动分析能力。
flowchart LR
subgraph Controller
A[Virtual Users] --> B[HTTP Requests]
B --> C[Application Server]
C --> D[(Database)]
end
E[Performance Agent] -- Polling --> C
E -- Sends Data --> F[Controller Monitor]
F --> G[Real-time Charts]
style A fill:#f9f,stroke:#333
style F fill:#bbf,stroke:#333,color:#fff
该架构图展示了监控代理如何桥接被测系统与Controller,实现端到端观测。
4.3.3 Web Performance Monitor集成实现端到端观测
为进一步提升诊断能力,可集成HP Diagnostics或第三方APM工具(如AppDynamics、Dynatrace)。这些工具能深入代码层级追踪慢事务根源,结合Controller的宏观负载视图,形成“自顶向下”的全栈性能分析体系。
例如,当发现某事务响应时间突增时,可通过WPM定位到具体SQL语句执行耗时过长,进而推动DBA优化索引结构。
总之,Controller不仅是负载发射器,更是性能数据的聚合中心。通过科学配置场景、精准调控负载、全面集成监控,才能真正发挥其在复杂分布式系统性能保障中的核心作用。
5. Analysis分析工具使用与性能指标解读
5.1 测试结果聚合与图表分析
LoadRunner Analysis模块是性能测试生命周期中的关键环节,负责将Controller执行过程中采集的海量原始数据进行清洗、聚合与可视化呈现。通过内置的多维度图表系统,测试工程师能够快速识别性能趋势与异常模式。
吞吐量、点击率、事务响应时间趋势图解读
在Analysis中, 吞吐量(Throughput) 表示单位时间内系统处理的字节数,通常以KB/sec为单位。高吞吐量意味着网络或服务器负载较重,需结合响应时间判断是否处于健康状态。
graph TD
A[开始测试] --> B{虚拟用户加压}
B --> C[监控吞吐量上升]
C --> D{是否伴随响应时间显著增长?}
D -- 是 --> E[可能存在瓶颈]
D -- 否 --> F[系统承载能力良好]
点击率(Hits per Second) 反映客户端向服务器发起请求的频率,适用于Web应用的压力评估。若点击率持续上升但吞吐量趋于平稳,可能表明存在静态资源缓存或带宽限制。
事务响应时间(Transaction Response Time) 图显示每个业务操作从发起至完成的时间分布。理想情况下应保持稳定波动;若出现“阶梯式”上升,则提示系统资源逐渐耗尽。
| 虚拟用户数 | 平均响应时间(ms) | 吞吐量(KB/s) | 点击率(/s) | 错误率(%) |
|---|---|---|---|---|
| 50 | 320 | 480 | 96 | 0 |
| 100 | 410 | 920 | 185 | 0.2 |
| 150 | 670 | 1310 | 260 | 1.5 |
| 200 | 1120 | 1580 | 310 | 5.8 |
| 250 | 2450 | 1600 | 315 | 18.3 |
| 300 | 3980 | 1590 | 312 | 34.7 |
| 350 | 5210 | 1420 | 280 | 56.1 |
| 400 | 6780 | 1100 | 210 | 78.9 |
| 450 | 8120 | 850 | 160 | 91.2 |
| 500 | 9450 | 620 | 120 | 96.8 |
该表展示了随着并发用户增加,系统性能逐步恶化的过程。当用户数超过200时,响应时间急剧上升,吞吐量接近饱和,错误率飙升,说明系统已达到拐点。
资源利用率瓶颈初步识别
Analysis支持导入来自目标系统的监控数据(如Windows PerfMon、Linux SAR、Oracle AWR等),可叠加显示CPU使用率、内存占用、磁盘I/O等待时间等指标。例如:
- 若 数据库等待时间 与事务响应时间高度正相关,则可能涉及慢SQL或索引缺失。
- 网络延迟 可通过“Time to First Buffer”指标观察,若其占比超过总响应时间的60%,应检查带宽或CDN配置。
不同虚拟用户组间性能差异对比分析
在复杂场景中,常设置多个Vuser Group模拟不同角色(如普通用户、VIP客户、后台管理员)。Analysis允许对各组的事务响应时间、吞吐量分别绘图并叠加比较,便于发现权限控制、资源隔离等问题。
操作步骤如下:
1. 在左侧“Legend”面板选择多个用户组;
2. 右键 → “Merge Graphs” → “Overlay”;
3. 选择同一Y轴指标(如响应时间);
4. 观察曲线分离程度,定位劣化最严重的用户路径。
此外,还可通过“Set Filter”功能筛选特定时间段的数据,排除初始化阶段干扰,聚焦稳态运行期的表现。
5.2 核心性能指标深度解析
平均响应时间与百分位数(P90/P95)意义
仅依赖平均响应时间易掩盖极端延迟问题。因此,LoadRunner推荐结合 百分位数 进行更精准评估:
- P90 :90%的请求响应时间低于此值;
- P95 :95%的请求满足该阈值;
- P99 :用于SLA承诺的关键指标。
例如,某交易系统要求“95%请求在2秒内完成”,则P95 ≤ 2000ms为达标标准。
可通过以下方式查看:
Results → Show Report → Summary Report → Transaction Performance Summary
其中列出各事务的Min、Max、Average及Std Dev,并支持导出CSV用于进一步统计分析。
错误率突增与系统拐点识别方法
错误类型包括超时(timeout)、连接拒绝(connection refused)、HTTP 5xx等。当错误率突然跃升(如从<1%跳至>10%),往往标志着系统进入不可靠区间。
拐点识别技巧:
- 绘制“响应时间 vs 用户数”散点图;
- 找到斜率明显变陡的位置;
- 结合吞吐量曲线确认是否已达平台期;
- 标记该点作为最大推荐并发数。
吞吐量饱和曲线与最大承载能力估算
绘制“吞吐量 vs 时间”曲线,若在用户持续增加的情况下吞吐量不再提升甚至下降,说明系统已达极限。此时可估算:
- 最大TPS(Transactions Per Second)
- 最优并发用户数(Optimal Load Level)
公式参考:
Max Capacity ≈ Throughput_peak / Avg_Transaction_Size
该值可用于容量规划与硬件扩容决策。
5.3 系统性能瓶颈定位与故障诊断
结合服务器监控数据定位数据库慢查询
将PerfMon计数器中的 SQLServer:Wait Statistics\Lock Waits/sec 与事务响应时间关联绘图,若两者同步上升,则怀疑锁竞争。
进一步操作:
1. 导出LR Correlation ID;
2. 匹配数据库日志中的会话ID;
3. 使用SQL Profiler捕获对应执行计划;
4. 优化缺失索引或重构长事务。
线程阻塞与连接池耗尽问题追溯
Java应用常见因线程池满导致请求排队。可通过JVM监控插件(如JMX)采集:
- Active Threads
- Queue Size
- Rejected Executions
当Rejected Execution > 0且响应时间激增,基本可判定线程池配置不足。
使用TruClient技术还原前端渲染性能影响
传统HTTP协议脚本无法捕捉JavaScript执行、DOM加载等前端耗时。启用TruClient IE/Chrome协议后,Analysis可展示:
- 页面完全加载时间
- 首屏渲染延迟
- AJAX调用链耗时
这对于现代SPA(单页应用)性能分析至关重要。
5.4 实际项目中LoadRunner全流程应用实战
多协议混合测试场景构建(HTTP + DB + FTP)
企业级系统常涉及跨协议交互。例如电商平台下单流程包含:
- HTTP:用户浏览商品
- ODBC:扣减库存
- FTP:上传订单附件
VuGen支持在同一脚本中嵌套多种协议函数:
lr_start_transaction("PlaceOrder");
web_submit_data("SubmitOrder",
"Action=https://shop.example.com/order",
ITEMDATA,
"Name=product_id", "Value=1001", ENDITEM,
LAST);
// 数据库验证库存
sql_connect("QueryStock", "DSN=InventoryDB;UID=user;PWD=pwd;");
sql_execute("SELECT stock FROM products WHERE id=1001");
sql_save_val("stock", "OutParam");
if (atoi(lr_eval_string("{stock}")) < 1) {
lr_output_message("Stock insufficient!");
lr_abort();
}
// 上传凭证
ftp_put("SourceFile=C:\\receipt.pdf",
"TargetFile=/uploads/{order_id}.pdf",
"TransferMode=BINARY",
LAST);
lr_end_transaction("PlaceOrder", LR_AUTO);
分布式测试环境部署与负载均衡协调
大型测试需多台Load Generator协同工作。Controller中配置步骤:
1. 添加LG机器并安装Agent;
2. 设置防火墙开放4449端口;
3. 在Scenario → Load Generators中连接;
4. 分配Vuser比例(如LG1: 40%, LG2: 60%);
5. 启用“Run on Load Generator as a process”。
注意事项:
- 确保所有LG时间同步(NTP)
- 避免单一网段带宽打满
- 监控LG自身资源消耗防止反向拖累
全周期性能报告输出与优化建议提出
Analysis提供标准报告模板(Standard, Custom, Web-only),支持一键生成PDF/HTML格式文档。
典型报告结构包括:
1. 测试概述(目标、环境、工具版本)
2. 场景设计(用户模型、加压策略)
3. 关键指标摘要(响应时间、吞吐量、错误率)
4. 瓶颈分析(图表+根因推断)
5. 优化建议(如:增加Redis缓存、拆分大事务、升级DB IOPS)
最终报告不仅是交付物,更是推动开发、运维团队协同改进的重要依据。
简介:LoadRunner是IT行业中广泛使用的高性能负载与压力测试工具,能够模拟大量并发用户,检测系统在高负载下的稳定性与性能表现。本资料涵盖LoadRunner核心组件VUGen、Controller和Analysis的使用方法,介绍基于C语言风格的VuGen脚本编写、多协议支持、测试场景设计及分布式测试实现。通过实际操作演练,帮助测试人员掌握从脚本录制、场景配置到结果分析的完整流程,提升软件性能测试能力,为系统优化提供数据支撑。
更多推荐
所有评论(0)