性能测试从入门到精通-LoadRunner实战(下)

第5章 场景设计实战

5.1 手动场景

🎭 比喻:手动挡汽车

手动场景就像开手动挡汽车------你完全控制油门和档位,想加速就加速,想减速就减速。
#mermaid-svg-doxW5IieQlKbvXVo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-doxW5IieQlKbvXVo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-doxW5IieQlKbvXVo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-doxW5IieQlKbvXVo .error-icon{fill:#552222;}#mermaid-svg-doxW5IieQlKbvXVo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-doxW5IieQlKbvXVo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-doxW5IieQlKbvXVo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-doxW5IieQlKbvXVo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-doxW5IieQlKbvXVo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-doxW5IieQlKbvXVo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-doxW5IieQlKbvXVo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-doxW5IieQlKbvXVo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-doxW5IieQlKbvXVo .marker.cross{stroke:#333333;}#mermaid-svg-doxW5IieQlKbvXVo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-doxW5IieQlKbvXVo p{margin:0;}#mermaid-svg-doxW5IieQlKbvXVo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-doxW5IieQlKbvXVo .cluster-label text{fill:#333;}#mermaid-svg-doxW5IieQlKbvXVo .cluster-label span{color:#333;}#mermaid-svg-doxW5IieQlKbvXVo .cluster-label span p{background-color:transparent;}#mermaid-svg-doxW5IieQlKbvXVo .label text,#mermaid-svg-doxW5IieQlKbvXVo span{fill:#333;color:#333;}#mermaid-svg-doxW5IieQlKbvXVo .node rect,#mermaid-svg-doxW5IieQlKbvXVo .node circle,#mermaid-svg-doxW5IieQlKbvXVo .node ellipse,#mermaid-svg-doxW5IieQlKbvXVo .node polygon,#mermaid-svg-doxW5IieQlKbvXVo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-doxW5IieQlKbvXVo .rough-node .label text,#mermaid-svg-doxW5IieQlKbvXVo .node .label text,#mermaid-svg-doxW5IieQlKbvXVo .image-shape .label,#mermaid-svg-doxW5IieQlKbvXVo .icon-shape .label{text-anchor:middle;}#mermaid-svg-doxW5IieQlKbvXVo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-doxW5IieQlKbvXVo .rough-node .label,#mermaid-svg-doxW5IieQlKbvXVo .node .label,#mermaid-svg-doxW5IieQlKbvXVo .image-shape .label,#mermaid-svg-doxW5IieQlKbvXVo .icon-shape .label{text-align:center;}#mermaid-svg-doxW5IieQlKbvXVo .node.clickable{cursor:pointer;}#mermaid-svg-doxW5IieQlKbvXVo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-doxW5IieQlKbvXVo .arrowheadPath{fill:#333333;}#mermaid-svg-doxW5IieQlKbvXVo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-doxW5IieQlKbvXVo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-doxW5IieQlKbvXVo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-doxW5IieQlKbvXVo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-doxW5IieQlKbvXVo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-doxW5IieQlKbvXVo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-doxW5IieQlKbvXVo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-doxW5IieQlKbvXVo .cluster text{fill:#333;}#mermaid-svg-doxW5IieQlKbvXVo .cluster span{color:#333;}#mermaid-svg-doxW5IieQlKbvXVo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-doxW5IieQlKbvXVo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-doxW5IieQlKbvXVo rect.text{fill:none;stroke-width:0;}#mermaid-svg-doxW5IieQlKbvXVo .icon-shape,#mermaid-svg-doxW5IieQlKbvXVo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-doxW5IieQlKbvXVo .icon-shape p,#mermaid-svg-doxW5IieQlKbvXVo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-doxW5IieQlKbvXVo .icon-shape .label rect,#mermaid-svg-doxW5IieQlKbvXVo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-doxW5IieQlKbvXVo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-doxW5IieQlKbvXVo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-doxW5IieQlKbvXVo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 一次性启动
分批启动
自定义
创建手动场景
添加脚本
配置VUser数量
设置调度策略
选择调度模式
所有VUser同时开始
按计划逐步增加VUser
完全自定义每个阶段的VUser数
配置运行时长
设置停止策略
完成场景设计

📊 手动场景配置示例

#mermaid-svg-FlKJACSUfnFQQnrt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FlKJACSUfnFQQnrt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FlKJACSUfnFQQnrt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FlKJACSUfnFQQnrt .error-icon{fill:#552222;}#mermaid-svg-FlKJACSUfnFQQnrt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FlKJACSUfnFQQnrt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FlKJACSUfnFQQnrt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FlKJACSUfnFQQnrt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FlKJACSUfnFQQnrt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FlKJACSUfnFQQnrt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FlKJACSUfnFQQnrt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FlKJACSUfnFQQnrt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FlKJACSUfnFQQnrt .marker.cross{stroke:#333333;}#mermaid-svg-FlKJACSUfnFQQnrt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FlKJACSUfnFQQnrt p{margin:0;}#mermaid-svg-FlKJACSUfnFQQnrt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FlKJACSUfnFQQnrt .cluster-label text{fill:#333;}#mermaid-svg-FlKJACSUfnFQQnrt .cluster-label span{color:#333;}#mermaid-svg-FlKJACSUfnFQQnrt .cluster-label span p{background-color:transparent;}#mermaid-svg-FlKJACSUfnFQQnrt .label text,#mermaid-svg-FlKJACSUfnFQQnrt span{fill:#333;color:#333;}#mermaid-svg-FlKJACSUfnFQQnrt .node rect,#mermaid-svg-FlKJACSUfnFQQnrt .node circle,#mermaid-svg-FlKJACSUfnFQQnrt .node ellipse,#mermaid-svg-FlKJACSUfnFQQnrt .node polygon,#mermaid-svg-FlKJACSUfnFQQnrt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FlKJACSUfnFQQnrt .rough-node .label text,#mermaid-svg-FlKJACSUfnFQQnrt .node .label text,#mermaid-svg-FlKJACSUfnFQQnrt .image-shape .label,#mermaid-svg-FlKJACSUfnFQQnrt .icon-shape .label{text-anchor:middle;}#mermaid-svg-FlKJACSUfnFQQnrt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FlKJACSUfnFQQnrt .rough-node .label,#mermaid-svg-FlKJACSUfnFQQnrt .node .label,#mermaid-svg-FlKJACSUfnFQQnrt .image-shape .label,#mermaid-svg-FlKJACSUfnFQQnrt .icon-shape .label{text-align:center;}#mermaid-svg-FlKJACSUfnFQQnrt .node.clickable{cursor:pointer;}#mermaid-svg-FlKJACSUfnFQQnrt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FlKJACSUfnFQQnrt .arrowheadPath{fill:#333333;}#mermaid-svg-FlKJACSUfnFQQnrt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FlKJACSUfnFQQnrt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FlKJACSUfnFQQnrt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FlKJACSUfnFQQnrt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FlKJACSUfnFQQnrt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FlKJACSUfnFQQnrt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FlKJACSUfnFQQnrt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FlKJACSUfnFQQnrt .cluster text{fill:#333;}#mermaid-svg-FlKJACSUfnFQQnrt .cluster span{color:#333;}#mermaid-svg-FlKJACSUfnFQQnrt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FlKJACSUfnFQQnrt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FlKJACSUfnFQQnrt rect.text{fill:none;stroke-width:0;}#mermaid-svg-FlKJACSUfnFQQnrt .icon-shape,#mermaid-svg-FlKJACSUfnFQQnrt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FlKJACSUfnFQQnrt .icon-shape p,#mermaid-svg-FlKJACSUfnFQQnrt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FlKJACSUfnFQQnrt .icon-shape .label rect,#mermaid-svg-FlKJACSUfnFQQnrt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FlKJACSUfnFQQnrt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FlKJACSUfnFQQnrt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FlKJACSUfnFQQnrt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 手动场景配置示例:电商大促
阶段3:冷却期(15-20分钟)
阶段2:高峰期(5-15分钟)
阶段1:预热期(0-5分钟)
15-18分钟:500→50 VUser

每分钟减少150个
0-2分钟:10→50 VUser

每分钟增加20个
2-5分钟:保持50 VUser
5-8分钟:50→500 VUser

每分钟增加150个
8-15分钟:保持500 VUser

🔥 峰值压力
18-20分钟:保持50 VUser

📝 场景设计步骤

c 复制代码
/*
 * ============================================
 * 场景设计步骤说明
 * ============================================
 *
 * 步骤1:打开 Controller → File → New Scenario
 * 步骤2:选择 "Manual Scenario"
 * 步骤3:添加脚本(浏览、下单、支付等)
 * 步骤4:为每个脚本设置 VUser 数量
 *        - 浏览脚本:200 VUser
 *        - 下单脚本:100 VUser
 *        - 支付脚本:50 VUser
 * 步骤5:设置 Load Generator
 *        - 本地机器:150 VUser
 *        - Generator-PC1:200 VUser
 * 步骤7:配置 Schedule
 *        - 预热期:5分钟
 *        - 高峰期:10分钟
 *        - 冷却期:5分钟
 * 步骤8:添加监控器
 *        - Windows Resources
 *        - IIS/WebLogic 监控
 *        - 数据库监控
 * 步骤9:保存场景
 * 步骤10:点击 Start Scenario 开始测试
 */

5.2 目标导向场景

🎭 比喻:自动驾驶

目标导向场景就像自动驾驶------你告诉它"我要在 3 秒内到达"(设定性能目标),它会自动调整 VUser 数量来找到满足目标的配置。
#mermaid-svg-4xNVAYdBOl1aRkP8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4xNVAYdBOl1aRkP8 .error-icon{fill:#552222;}#mermaid-svg-4xNVAYdBOl1aRkP8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4xNVAYdBOl1aRkP8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .marker.cross{stroke:#333333;}#mermaid-svg-4xNVAYdBOl1aRkP8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4xNVAYdBOl1aRkP8 p{margin:0;}#mermaid-svg-4xNVAYdBOl1aRkP8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .cluster-label text{fill:#333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .cluster-label span{color:#333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .cluster-label span p{background-color:transparent;}#mermaid-svg-4xNVAYdBOl1aRkP8 .label text,#mermaid-svg-4xNVAYdBOl1aRkP8 span{fill:#333;color:#333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .node rect,#mermaid-svg-4xNVAYdBOl1aRkP8 .node circle,#mermaid-svg-4xNVAYdBOl1aRkP8 .node ellipse,#mermaid-svg-4xNVAYdBOl1aRkP8 .node polygon,#mermaid-svg-4xNVAYdBOl1aRkP8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4xNVAYdBOl1aRkP8 .rough-node .label text,#mermaid-svg-4xNVAYdBOl1aRkP8 .node .label text,#mermaid-svg-4xNVAYdBOl1aRkP8 .image-shape .label,#mermaid-svg-4xNVAYdBOl1aRkP8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-4xNVAYdBOl1aRkP8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4xNVAYdBOl1aRkP8 .rough-node .label,#mermaid-svg-4xNVAYdBOl1aRkP8 .node .label,#mermaid-svg-4xNVAYdBOl1aRkP8 .image-shape .label,#mermaid-svg-4xNVAYdBOl1aRkP8 .icon-shape .label{text-align:center;}#mermaid-svg-4xNVAYdBOl1aRkP8 .node.clickable{cursor:pointer;}#mermaid-svg-4xNVAYdBOl1aRkP8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .arrowheadPath{fill:#333333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4xNVAYdBOl1aRkP8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4xNVAYdBOl1aRkP8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4xNVAYdBOl1aRkP8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4xNVAYdBOl1aRkP8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4xNVAYdBOl1aRkP8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4xNVAYdBOl1aRkP8 .cluster text{fill:#333;}#mermaid-svg-4xNVAYdBOl1aRkP8 .cluster span{color:#333;}#mermaid-svg-4xNVAYdBOl1aRkP8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4xNVAYdBOl1aRkP8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4xNVAYdBOl1aRkP8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-4xNVAYdBOl1aRkP8 .icon-shape,#mermaid-svg-4xNVAYdBOl1aRkP8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4xNVAYdBOl1aRkP8 .icon-shape p,#mermaid-svg-4xNVAYdBOl1aRkP8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4xNVAYdBOl1aRkP8 .icon-shape .label rect,#mermaid-svg-4xNVAYdBOl1aRkP8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4xNVAYdBOl1aRkP8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4xNVAYdBOl1aRkP8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4xNVAYdBOl1aRkP8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 响应时间
吞吐量
并发数
VUser数
创建目标导向场景
选择目标类型
设定:事务响应时间

不超过3秒
设定:每秒处理

100个事务
设定:同时在线

500个用户
设定:最多

1000个VUser
配置目标详情
设置行为参数

最小/最大VUser数
开始测试
LoadRunner自动调优
输出结果

📊 目标类型详解

目标类型 说明 典型场景
响应时间 确保事务在指定时间内完成 银行转账必须在3秒内完成
每秒点击数 确保系统每秒能处理指定点击数 首页每秒处理50次点击
每秒事务数 确保系统每秒能处理指定事务数 支付系统每秒处理100笔交易
并发VUser数 测试指定数量VUser下的性能 模拟500人同时在线
页面吞吐量 确保每秒能传输指定数据量 视频网站每秒传输1GB

5.3 百分比模式

🎭 比喻:分配舞台时间

百分比模式就像给不同的演员分配舞台时间------比如主角占 60% 的戏份,配角占 30%,群演占 10%。
#mermaid-svg-IhXVbiU7IuNFRRGq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IhXVbiU7IuNFRRGq .error-icon{fill:#552222;}#mermaid-svg-IhXVbiU7IuNFRRGq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IhXVbiU7IuNFRRGq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IhXVbiU7IuNFRRGq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IhXVbiU7IuNFRRGq .marker.cross{stroke:#333333;}#mermaid-svg-IhXVbiU7IuNFRRGq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IhXVbiU7IuNFRRGq p{margin:0;}#mermaid-svg-IhXVbiU7IuNFRRGq .pieCircle{stroke:#000000;stroke-width:2px;opacity:0.7;}#mermaid-svg-IhXVbiU7IuNFRRGq .pieOuterCircle{stroke:#000000;stroke-width:1px;fill:none;}#mermaid-svg-IhXVbiU7IuNFRRGq .pieTitleText{text-anchor:middle;font-size:25px;fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-IhXVbiU7IuNFRRGq .slice{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#000000;font-size:17px;}#mermaid-svg-IhXVbiU7IuNFRRGq .legend text{fill:#000000;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:17px;}#mermaid-svg-IhXVbiU7IuNFRRGq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 60%20%15%5%电商系统用户行为分布 浏览商品(60%) 搜索商品(20%) 下单支付(15%) 客服咨询(5%)

📝 百分比模式配置

复制代码
场景名称:电商日常负载

脚本1:browse_product(浏览商品)
  - 百分比:60%
  - VUser 数量:由总VUser数按比例分配

脚本2:search_product(搜索商品)
  - 百分比:20%
  - VUser 数量:由总VUser数按比例分配

脚本3:place_order(下单支付)
  - 百分比:15%
  - VUser 数量:由总VUser数按比例分配

脚本4:customer_service(客服咨询)
  - 百分比:5%
  - VUser 数量:由总VUser数按比例分配

总 VUser 数:1000
  → browse_product: 600 VUser
  → search_product: 200 VUser
  → place_order: 150 VUser
  → customer_service: 50 VUser

第6章 完整Demo:银行转账系统性能测试

6.1 项目背景

🏦 银行转账系统介绍

#mermaid-svg-knqBKx8e1lkMtBfx{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-knqBKx8e1lkMtBfx .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-knqBKx8e1lkMtBfx .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-knqBKx8e1lkMtBfx .error-icon{fill:#552222;}#mermaid-svg-knqBKx8e1lkMtBfx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-knqBKx8e1lkMtBfx .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-knqBKx8e1lkMtBfx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-knqBKx8e1lkMtBfx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-knqBKx8e1lkMtBfx .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-knqBKx8e1lkMtBfx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-knqBKx8e1lkMtBfx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-knqBKx8e1lkMtBfx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-knqBKx8e1lkMtBfx .marker.cross{stroke:#333333;}#mermaid-svg-knqBKx8e1lkMtBfx svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-knqBKx8e1lkMtBfx p{margin:0;}#mermaid-svg-knqBKx8e1lkMtBfx .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-knqBKx8e1lkMtBfx .cluster-label text{fill:#333;}#mermaid-svg-knqBKx8e1lkMtBfx .cluster-label span{color:#333;}#mermaid-svg-knqBKx8e1lkMtBfx .cluster-label span p{background-color:transparent;}#mermaid-svg-knqBKx8e1lkMtBfx .label text,#mermaid-svg-knqBKx8e1lkMtBfx span{fill:#333;color:#333;}#mermaid-svg-knqBKx8e1lkMtBfx .node rect,#mermaid-svg-knqBKx8e1lkMtBfx .node circle,#mermaid-svg-knqBKx8e1lkMtBfx .node ellipse,#mermaid-svg-knqBKx8e1lkMtBfx .node polygon,#mermaid-svg-knqBKx8e1lkMtBfx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-knqBKx8e1lkMtBfx .rough-node .label text,#mermaid-svg-knqBKx8e1lkMtBfx .node .label text,#mermaid-svg-knqBKx8e1lkMtBfx .image-shape .label,#mermaid-svg-knqBKx8e1lkMtBfx .icon-shape .label{text-anchor:middle;}#mermaid-svg-knqBKx8e1lkMtBfx .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-knqBKx8e1lkMtBfx .rough-node .label,#mermaid-svg-knqBKx8e1lkMtBfx .node .label,#mermaid-svg-knqBKx8e1lkMtBfx .image-shape .label,#mermaid-svg-knqBKx8e1lkMtBfx .icon-shape .label{text-align:center;}#mermaid-svg-knqBKx8e1lkMtBfx .node.clickable{cursor:pointer;}#mermaid-svg-knqBKx8e1lkMtBfx .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-knqBKx8e1lkMtBfx .arrowheadPath{fill:#333333;}#mermaid-svg-knqBKx8e1lkMtBfx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-knqBKx8e1lkMtBfx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-knqBKx8e1lkMtBfx .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-knqBKx8e1lkMtBfx .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-knqBKx8e1lkMtBfx .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-knqBKx8e1lkMtBfx .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-knqBKx8e1lkMtBfx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-knqBKx8e1lkMtBfx .cluster text{fill:#333;}#mermaid-svg-knqBKx8e1lkMtBfx .cluster span{color:#333;}#mermaid-svg-knqBKx8e1lkMtBfx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-knqBKx8e1lkMtBfx .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-knqBKx8e1lkMtBfx rect.text{fill:none;stroke-width:0;}#mermaid-svg-knqBKx8e1lkMtBfx .icon-shape,#mermaid-svg-knqBKx8e1lkMtBfx .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-knqBKx8e1lkMtBfx .icon-shape p,#mermaid-svg-knqBKx8e1lkMtBfx .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-knqBKx8e1lkMtBfx .icon-shape .label rect,#mermaid-svg-knqBKx8e1lkMtBfx .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-knqBKx8e1lkMtBfx .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-knqBKx8e1lkMtBfx .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-knqBKx8e1lkMtBfx :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 银行转账系统架构
数据层
应用层
接入层
用户层
主数据库

MySQL
Web浏览器
负载均衡器

Nginx
手机APP
ATM机
API网关
转账服务1
转账服务2
账户服务
风控服务
Redis缓存
消息队列

RabbitMQ
从数据库

MySQL

📋 性能测试需求

指标 目标值 说明
并发用户数 1000 同时在线用户
转账响应时间 < 3秒(95%) 95%的请求在3秒内完成
查询响应时间 < 1秒(95%) 95%的查询在1秒内完成
TPS >= 500 每秒处理事务数
错误率 < 0.1% 错误请求占比
系统可用性 99.9% 测试期间系统不能宕机

6.2 测试计划

#mermaid-svg-LcYm7Vt01s0zh88t{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LcYm7Vt01s0zh88t .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LcYm7Vt01s0zh88t .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LcYm7Vt01s0zh88t .error-icon{fill:#552222;}#mermaid-svg-LcYm7Vt01s0zh88t .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LcYm7Vt01s0zh88t .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LcYm7Vt01s0zh88t .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LcYm7Vt01s0zh88t .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LcYm7Vt01s0zh88t .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LcYm7Vt01s0zh88t .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LcYm7Vt01s0zh88t .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LcYm7Vt01s0zh88t .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LcYm7Vt01s0zh88t .marker.cross{stroke:#333333;}#mermaid-svg-LcYm7Vt01s0zh88t svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LcYm7Vt01s0zh88t p{margin:0;}#mermaid-svg-LcYm7Vt01s0zh88t .mermaid-main-font{font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-LcYm7Vt01s0zh88t .exclude-range{fill:#eeeeee;}#mermaid-svg-LcYm7Vt01s0zh88t .section{stroke:none;opacity:0.2;}#mermaid-svg-LcYm7Vt01s0zh88t .section0{fill:rgba(102, 102, 255, 0.49);}#mermaid-svg-LcYm7Vt01s0zh88t .section2{fill:#fff400;}#mermaid-svg-LcYm7Vt01s0zh88t .section1,#mermaid-svg-LcYm7Vt01s0zh88t .section3{fill:white;opacity:0.2;}#mermaid-svg-LcYm7Vt01s0zh88t .sectionTitle0{fill:#333;}#mermaid-svg-LcYm7Vt01s0zh88t .sectionTitle1{fill:#333;}#mermaid-svg-LcYm7Vt01s0zh88t .sectionTitle2{fill:#333;}#mermaid-svg-LcYm7Vt01s0zh88t .sectionTitle3{fill:#333;}#mermaid-svg-LcYm7Vt01s0zh88t .sectionTitle{text-anchor:start;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-LcYm7Vt01s0zh88t .grid .tick{stroke:lightgrey;opacity:0.8;shape-rendering:crispEdges;}#mermaid-svg-LcYm7Vt01s0zh88t .grid .tick text{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#333;}#mermaid-svg-LcYm7Vt01s0zh88t .grid path{stroke-width:0;}#mermaid-svg-LcYm7Vt01s0zh88t .today{fill:none;stroke:red;stroke-width:2px;}#mermaid-svg-LcYm7Vt01s0zh88t .task{stroke-width:2;}#mermaid-svg-LcYm7Vt01s0zh88t .taskText{text-anchor:middle;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutsideRight{fill:black;text-anchor:start;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutsideLeft{fill:black;text-anchor:end;}#mermaid-svg-LcYm7Vt01s0zh88t .task.clickable{cursor:pointer;}#mermaid-svg-LcYm7Vt01s0zh88t .taskText.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-LcYm7Vt01s0zh88t .taskText0,#mermaid-svg-LcYm7Vt01s0zh88t .taskText1,#mermaid-svg-LcYm7Vt01s0zh88t .taskText2,#mermaid-svg-LcYm7Vt01s0zh88t .taskText3{fill:white;}#mermaid-svg-LcYm7Vt01s0zh88t .task0,#mermaid-svg-LcYm7Vt01s0zh88t .task1,#mermaid-svg-LcYm7Vt01s0zh88t .task2,#mermaid-svg-LcYm7Vt01s0zh88t .task3{fill:#8a90dd;stroke:#534fbc;}#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutside0,#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutside2{fill:black;}#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutside1,#mermaid-svg-LcYm7Vt01s0zh88t .taskTextOutside3{fill:black;}#mermaid-svg-LcYm7Vt01s0zh88t .active0,#mermaid-svg-LcYm7Vt01s0zh88t .active1,#mermaid-svg-LcYm7Vt01s0zh88t .active2,#mermaid-svg-LcYm7Vt01s0zh88t .active3{fill:#bfc7ff;stroke:#534fbc;}#mermaid-svg-LcYm7Vt01s0zh88t .activeText0,#mermaid-svg-LcYm7Vt01s0zh88t .activeText1,#mermaid-svg-LcYm7Vt01s0zh88t .activeText2,#mermaid-svg-LcYm7Vt01s0zh88t .activeText3{fill:black!important;}#mermaid-svg-LcYm7Vt01s0zh88t .done0,#mermaid-svg-LcYm7Vt01s0zh88t .done1,#mermaid-svg-LcYm7Vt01s0zh88t .done2,#mermaid-svg-LcYm7Vt01s0zh88t .done3{stroke:grey;fill:lightgrey;stroke-width:2;}#mermaid-svg-LcYm7Vt01s0zh88t .doneText0,#mermaid-svg-LcYm7Vt01s0zh88t .doneText1,#mermaid-svg-LcYm7Vt01s0zh88t .doneText2,#mermaid-svg-LcYm7Vt01s0zh88t .doneText3{fill:black!important;}#mermaid-svg-LcYm7Vt01s0zh88t .doneText0.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneText0.taskTextOutsideRight,#mermaid-svg-LcYm7Vt01s0zh88t .doneText1.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneText1.taskTextOutsideRight,#mermaid-svg-LcYm7Vt01s0zh88t .doneText2.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneText2.taskTextOutsideRight,#mermaid-svg-LcYm7Vt01s0zh88t .doneText3.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-LcYm7Vt01s0zh88t .crit0,#mermaid-svg-LcYm7Vt01s0zh88t .crit1,#mermaid-svg-LcYm7Vt01s0zh88t .crit2,#mermaid-svg-LcYm7Vt01s0zh88t .crit3{stroke:#ff8888;fill:red;stroke-width:2;}#mermaid-svg-LcYm7Vt01s0zh88t .activeCrit0,#mermaid-svg-LcYm7Vt01s0zh88t .activeCrit1,#mermaid-svg-LcYm7Vt01s0zh88t .activeCrit2,#mermaid-svg-LcYm7Vt01s0zh88t .activeCrit3{stroke:#ff8888;fill:#bfc7ff;stroke-width:2;}#mermaid-svg-LcYm7Vt01s0zh88t .doneCrit0,#mermaid-svg-LcYm7Vt01s0zh88t .doneCrit1,#mermaid-svg-LcYm7Vt01s0zh88t .doneCrit2,#mermaid-svg-LcYm7Vt01s0zh88t .doneCrit3{stroke:#ff8888;fill:lightgrey;stroke-width:2;cursor:pointer;shape-rendering:crispEdges;}#mermaid-svg-LcYm7Vt01s0zh88t .milestone{transform:rotate(45deg) scale(0.8,0.8);}#mermaid-svg-LcYm7Vt01s0zh88t .milestoneText{font-style:italic;}#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText0,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText1,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText2,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText3{fill:black!important;}#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText0.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText0.taskTextOutsideRight,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText1.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText1.taskTextOutsideRight,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText2.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText2.taskTextOutsideRight,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText3.taskTextOutsideLeft,#mermaid-svg-LcYm7Vt01s0zh88t .doneCritText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-LcYm7Vt01s0zh88t .vert{stroke:navy;}#mermaid-svg-LcYm7Vt01s0zh88t .vertText{font-size:15px;text-anchor:middle;fill:navy!important;}#mermaid-svg-LcYm7Vt01s0zh88t .activeCritText0,#mermaid-svg-LcYm7Vt01s0zh88t .activeCritText1,#mermaid-svg-LcYm7Vt01s0zh88t .activeCritText2,#mermaid-svg-LcYm7Vt01s0zh88t .activeCritText3{fill:black!important;}#mermaid-svg-LcYm7Vt01s0zh88t .titleText{text-anchor:middle;font-size:18px;fill:#333;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-LcYm7Vt01s0zh88t :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 环境搭建 测试数据准备 录制转账脚本 脚本增强(参数化等) 脚本调试 设计测试场景 配置监控 基准测试 负载测试 压力测试 稳定性测试 数据分析 报告编写 问题跟踪 准备阶段脚本开发场景设计执行测试分析报告 银行转账系统性能测试计划


6.3 脚本开发

📝 完整银行转账脚本

c 复制代码
/*
 * ============================================
 * 银行转账系统 - 完整性能测试脚本
 * 协议:Web (HTTP/HTML)
 * 版本:1.0
 * ============================================
 */

// ========== 全局变量 ==========
int retryCount = 0;
int maxRetry = 3;


// ========== vuser_init:初始化与登录 ==========
vuser_init()
{
    int rc;

    // 设置超时时间
    web_set_timeout("CONNECT", "60");
    web_set_timeout("RECEIVE", "120");

    // 生成随机数据
    srand(time(NULL));

    // 访问银行首页
    web_url("bank_home",
        "URL=http://bank.example.com/",
        "TargetFrame=",
        "Resource=0",
        "RecContentType=text/html",
        LAST);

    // 登录
    lr_start_transaction("bank_login");

    // 关联 CSRF Token
    web_reg_save_param("csrfToken",
        "LB=name=\"_csrf\" value=\"",
        "RB=\"",
        "Search=Body",
        LAST);

    // 关联 sessionID
    web_reg_save_param("sessionId",
        "LB=JSESSIONID=",
        "RB=;",
        "Search=Headers",
        LAST);

    web_submit_data("login_submit",
        "Action=http://bank.example.com/api/auth/login",
        "Method=POST",
        "RecContentType=application/json",
        "Referer=http://bank.example.com/login",
        ITEMDATA,
        "Name=username", "Value={username}", ENDITEM,
        "Name=password", "Value={password}", ENDITEM,
        "Name=_csrf", "Value={csrfToken}", ENDITEM,
        "Name=deviceType", "Value=WEB", ENDITEM,
        LAST);

    // 验证登录结果
    web_reg_save_param_json("loginCode",
        "QueryString=$.code",
        "Scope=Body",
        LAST);

    web_reg_save_param_json("loginMsg",
        "QueryString=$.message",
        "Scope=Body",
        LAST);

    if (atoi(lr_eval_string("{loginCode}")) == 0) {
        lr_output_message("登录成功: %s", lr_eval_string("{loginMsg}"));
        lr_end_transaction("bank_login", LR_PASS);
    } else {
        lr_error_message("登录失败: %s", lr_eval_string("{loginMsg}"));
        lr_end_transaction("bank_login", LR_FAIL);
        return -1;  // 登录失败,终止VUser
    }

    return 0;
}


// ========== Action:主要业务操作 ==========
Action()
{
    // ==========================================
    // 步骤1:查询账户余额
    // ==========================================
    lr_start_transaction("bank_query_balance");

    web_reg_save_param_json("balance",
        "QueryString=$.data.balance",
        "Scope=Body",
        LAST);

    web_reg_save_param_json("accountName",
        "QueryString=$.data.accountName",
        "Scope=Body",
        LAST);

    web_custom_request("queryBalance",
        "URL=http://bank.example.com/api/account/{accountId}/balance",
        "Method=GET",
        "Resource=0",
        "RecContentType=application/json",
        "Mode=HTML",
        "EncType=application/json",
        LAST);

    lr_output_message("账户: %s, 余额: %s",
        lr_eval_string("{accountName}"),
        lr_eval_string("{balance}"));

    lr_end_transaction("bank_query_balance", LR_AUTO);

    lr_think_time(2);  // 用户查看余额,思考2秒


    // ==========================================
    // 步骤2:查询转账记录
    // ==========================================
    lr_start_transaction("bank_query_history");

    web_custom_request("queryHistory",
        "URL=http://bank.example.com/api/transfer/history?accountId={accountId}&page=1&size=10",
        "Method=GET",
        "Resource=0",
        "RecContentType=application/json",
        "Mode=HTML",
        LAST);

    lr_end_transaction("bank_query_history", LR_AUTO);

    lr_think_time(3);  // 用户查看记录,思考3秒


    // ==========================================
    // 步骤3:执行转账(核心业务)
    // ==========================================
    lr_start_transaction("bank_do_transfer");

    // 集合点:模拟集中转账高峰
    lr_rendezvous("transfer_peak");

    // 构造转账请求
    char transferBody[2048];
    sprintf(transferBody,
        "{"
        "\"fromAccount\":\"%s\","
        "\"toAccount\":\"%s\","
        "\"amount\":%s,"
        "\"currency\":\"CNY\","
        "\"remark\":\"%s\","
        "\"payPassword\":\"%s\""
        "}",
        lr_eval_string("{fromAccount}"),
        lr_eval_string("{toAccount}"),
        lr_eval_string("{amount}"),
        lr_eval_string("{remark}"),
        lr_eval_string("{payPassword}")
    );

    // 关联转账结果
    web_reg_save_param_json("transferCode",
        "QueryString=$.code",
        "Scope=Body",
        LAST);

    web_reg_save_param_json("transferMsg",
        "QueryString=$.message",
        "Scope=Body",
        LAST);

    web_reg_save_param_json("transferId",
        "QueryString=$.data.transferId",
        "Scope=Body",
        LAST);

    // 重试机制
    retryCount = 0;
    do {
        web_custom_request("doTransfer",
            "URL=http://bank.example.com/api/transfer/execute",
            "Method=POST",
            "Resource=0",
            "RecContentType=application/json",
            "Mode=HTML",
            "Body={transferBody}",
            LAST);

        retryCount++;

        if (atoi(lr_eval_string("{transferCode}")) == 0) {
            break;  // 成功则退出重试
        }

        if (retryCount < maxRetry) {
            lr_output_message("转账失败,第 %d 次重试...", retryCount);
            lr_think_time(2);  // 等待2秒后重试
        }
    } while (retryCount < maxRetry);

    // 判断最终结果
    if (atoi(lr_eval_string("{transferCode}")) == 0) {
        lr_output_message("转账成功!流水号: %s",
            lr_eval_string("{transferId}"));
        lr_end_transaction("bank_do_transfer", LR_PASS);
    } else {
        lr_error_message("转账失败(重试%d次): %s",
            retryCount, lr_eval_string("{transferMsg}"));
        lr_end_transaction("bank_do_transfer", LR_FAIL);
    }

    lr_think_time(5);  // 用户确认转账结果,思考5秒


    // ==========================================
    // 步骤4:查询转账详情
    // ==========================================
    lr_start_transaction("bank_query_transfer_detail");

    web_custom_request("queryTransferDetail",
        "URL=http://bank.example.com/api/transfer/{transferId}/detail",
        "Method=GET",
        "Resource=0",
        "RecContentType=application/json",
        "Mode=HTML",
        LAST);

    lr_end_transaction("bank_query_transfer_detail", LR_AUTO);

    lr_think_time(2);

    return 0;
}


// ========== vuser_end:登出与清理 ==========
vuser_end()
{
    lr_start_transaction("bank_logout");

    web_custom_request("logout",
        "URL=http://bank.example.com/api/auth/logout",
        "Method=POST",
        "Resource=0",
        "RecContentType=application/json",
        "Mode=HTML",
        LAST);

    lr_end_transaction("bank_logout", LR_AUTO);

    return 0;
}

📊 参数文件配置

username.dat(用户名参数文件):

复制代码
username
user001
user002
user003
...
user999
user1000

password.dat(密码参数文件):

复制代码
password
pass001
pass002
pass003
...
pass999
pass1000

fromAccount.dat(转出账户):

复制代码
fromAccount
6222000000001001
6222000000001002
6222000000001003
...
6222000000010000

toAccount.dat(转入账户):

复制代码
toAccount
6222000000020001
6222000000020002
6222000000020003
...
6222000000029999

amount.dat(转账金额):

复制代码
amount
100.00
500.00
1000.00
5000.00
10000.00
50000.00
100000.00

6.4 场景执行

📋 测试场景设计

#mermaid-svg-1RPhhoZIAXJWUC6T{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1RPhhoZIAXJWUC6T .error-icon{fill:#552222;}#mermaid-svg-1RPhhoZIAXJWUC6T .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1RPhhoZIAXJWUC6T .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1RPhhoZIAXJWUC6T .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1RPhhoZIAXJWUC6T .marker.cross{stroke:#333333;}#mermaid-svg-1RPhhoZIAXJWUC6T svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1RPhhoZIAXJWUC6T p{margin:0;}#mermaid-svg-1RPhhoZIAXJWUC6T .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1RPhhoZIAXJWUC6T .cluster-label text{fill:#333;}#mermaid-svg-1RPhhoZIAXJWUC6T .cluster-label span{color:#333;}#mermaid-svg-1RPhhoZIAXJWUC6T .cluster-label span p{background-color:transparent;}#mermaid-svg-1RPhhoZIAXJWUC6T .label text,#mermaid-svg-1RPhhoZIAXJWUC6T span{fill:#333;color:#333;}#mermaid-svg-1RPhhoZIAXJWUC6T .node rect,#mermaid-svg-1RPhhoZIAXJWUC6T .node circle,#mermaid-svg-1RPhhoZIAXJWUC6T .node ellipse,#mermaid-svg-1RPhhoZIAXJWUC6T .node polygon,#mermaid-svg-1RPhhoZIAXJWUC6T .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1RPhhoZIAXJWUC6T .rough-node .label text,#mermaid-svg-1RPhhoZIAXJWUC6T .node .label text,#mermaid-svg-1RPhhoZIAXJWUC6T .image-shape .label,#mermaid-svg-1RPhhoZIAXJWUC6T .icon-shape .label{text-anchor:middle;}#mermaid-svg-1RPhhoZIAXJWUC6T .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1RPhhoZIAXJWUC6T .rough-node .label,#mermaid-svg-1RPhhoZIAXJWUC6T .node .label,#mermaid-svg-1RPhhoZIAXJWUC6T .image-shape .label,#mermaid-svg-1RPhhoZIAXJWUC6T .icon-shape .label{text-align:center;}#mermaid-svg-1RPhhoZIAXJWUC6T .node.clickable{cursor:pointer;}#mermaid-svg-1RPhhoZIAXJWUC6T .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1RPhhoZIAXJWUC6T .arrowheadPath{fill:#333333;}#mermaid-svg-1RPhhoZIAXJWUC6T .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1RPhhoZIAXJWUC6T .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1RPhhoZIAXJWUC6T .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1RPhhoZIAXJWUC6T .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1RPhhoZIAXJWUC6T .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1RPhhoZIAXJWUC6T .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1RPhhoZIAXJWUC6T .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1RPhhoZIAXJWUC6T .cluster text{fill:#333;}#mermaid-svg-1RPhhoZIAXJWUC6T .cluster span{color:#333;}#mermaid-svg-1RPhhoZIAXJWUC6T div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1RPhhoZIAXJWUC6T .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1RPhhoZIAXJWUC6T rect.text{fill:none;stroke-width:0;}#mermaid-svg-1RPhhoZIAXJWUC6T .icon-shape,#mermaid-svg-1RPhhoZIAXJWUC6T .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1RPhhoZIAXJWUC6T .icon-shape p,#mermaid-svg-1RPhhoZIAXJWUC6T .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1RPhhoZIAXJWUC6T .icon-shape .label rect,#mermaid-svg-1RPhhoZIAXJWUC6T .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1RPhhoZIAXJWUC6T .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1RPhhoZIAXJWUC6T .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1RPhhoZIAXJWUC6T :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 银行转账系统 - 测试场景矩阵
场景4:稳定性测试
800 VUser

运行24小时

目的:验证长时间稳定性
场景3:压力测试
1000→2000 VUser

持续加压直到崩溃

目的:找到系统极限
场景2:负载测试
100→1000 VUser

分5批增加

目的:验证目标指标
场景1:基准测试
100 VUser

运行30分钟

目的:建立性能基线

📊 负载测试执行计划

渲染错误: Mermaid 渲染失败: Invalid date:00:00


6.5 结果分析

📊 假设测试结果

#mermaid-svg-PKclqG7KgIsZpMBO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PKclqG7KgIsZpMBO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PKclqG7KgIsZpMBO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PKclqG7KgIsZpMBO .error-icon{fill:#552222;}#mermaid-svg-PKclqG7KgIsZpMBO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PKclqG7KgIsZpMBO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PKclqG7KgIsZpMBO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PKclqG7KgIsZpMBO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PKclqG7KgIsZpMBO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PKclqG7KgIsZpMBO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PKclqG7KgIsZpMBO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PKclqG7KgIsZpMBO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PKclqG7KgIsZpMBO .marker.cross{stroke:#333333;}#mermaid-svg-PKclqG7KgIsZpMBO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PKclqG7KgIsZpMBO p{margin:0;}#mermaid-svg-PKclqG7KgIsZpMBO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-PKclqG7KgIsZpMBO .cluster-label text{fill:#333;}#mermaid-svg-PKclqG7KgIsZpMBO .cluster-label span{color:#333;}#mermaid-svg-PKclqG7KgIsZpMBO .cluster-label span p{background-color:transparent;}#mermaid-svg-PKclqG7KgIsZpMBO .label text,#mermaid-svg-PKclqG7KgIsZpMBO span{fill:#333;color:#333;}#mermaid-svg-PKclqG7KgIsZpMBO .node rect,#mermaid-svg-PKclqG7KgIsZpMBO .node circle,#mermaid-svg-PKclqG7KgIsZpMBO .node ellipse,#mermaid-svg-PKclqG7KgIsZpMBO .node polygon,#mermaid-svg-PKclqG7KgIsZpMBO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PKclqG7KgIsZpMBO .rough-node .label text,#mermaid-svg-PKclqG7KgIsZpMBO .node .label text,#mermaid-svg-PKclqG7KgIsZpMBO .image-shape .label,#mermaid-svg-PKclqG7KgIsZpMBO .icon-shape .label{text-anchor:middle;}#mermaid-svg-PKclqG7KgIsZpMBO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PKclqG7KgIsZpMBO .rough-node .label,#mermaid-svg-PKclqG7KgIsZpMBO .node .label,#mermaid-svg-PKclqG7KgIsZpMBO .image-shape .label,#mermaid-svg-PKclqG7KgIsZpMBO .icon-shape .label{text-align:center;}#mermaid-svg-PKclqG7KgIsZpMBO .node.clickable{cursor:pointer;}#mermaid-svg-PKclqG7KgIsZpMBO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PKclqG7KgIsZpMBO .arrowheadPath{fill:#333333;}#mermaid-svg-PKclqG7KgIsZpMBO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PKclqG7KgIsZpMBO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PKclqG7KgIsZpMBO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PKclqG7KgIsZpMBO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PKclqG7KgIsZpMBO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PKclqG7KgIsZpMBO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PKclqG7KgIsZpMBO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PKclqG7KgIsZpMBO .cluster text{fill:#333;}#mermaid-svg-PKclqG7KgIsZpMBO .cluster span{color:#333;}#mermaid-svg-PKclqG7KgIsZpMBO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PKclqG7KgIsZpMBO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PKclqG7KgIsZpMBO rect.text{fill:none;stroke-width:0;}#mermaid-svg-PKclqG7KgIsZpMBO .icon-shape,#mermaid-svg-PKclqG7KgIsZpMBO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PKclqG7KgIsZpMBO .icon-shape p,#mermaid-svg-PKclqG7KgIsZpMBO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PKclqG7KgIsZpMBO .icon-shape .label rect,#mermaid-svg-PKclqG7KgIsZpMBO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PKclqG7KgIsZpMBO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PKclqG7KgIsZpMBO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PKclqG7KgIsZpMBO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 性能指标达标情况
转账响应时间

─────────

目标: < 3秒 (95%)

实际: 2.1秒 (95%)

✅ 达标
查询响应时间

─────────

目标: < 1秒 (95%)

实际: 0.6秒 (95%)

✅ 达标
TPS

─────────

目标: >= 500

实际: 620

✅ 达标
错误率

─────────

目标: < 0.1%

实际: 0.05%

✅ 达标
CPU使用率

─────────

目标: < 80%

实际: 75%

⚠️ 接近上限

🔍 瓶颈分析示例

#mermaid-svg-gSPEcACLSWsKIkdX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gSPEcACLSWsKIkdX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gSPEcACLSWsKIkdX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gSPEcACLSWsKIkdX .error-icon{fill:#552222;}#mermaid-svg-gSPEcACLSWsKIkdX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gSPEcACLSWsKIkdX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gSPEcACLSWsKIkdX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gSPEcACLSWsKIkdX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gSPEcACLSWsKIkdX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gSPEcACLSWsKIkdX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gSPEcACLSWsKIkdX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gSPEcACLSWsKIkdX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gSPEcACLSWsKIkdX .marker.cross{stroke:#333333;}#mermaid-svg-gSPEcACLSWsKIkdX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gSPEcACLSWsKIkdX p{margin:0;}#mermaid-svg-gSPEcACLSWsKIkdX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gSPEcACLSWsKIkdX .cluster-label text{fill:#333;}#mermaid-svg-gSPEcACLSWsKIkdX .cluster-label span{color:#333;}#mermaid-svg-gSPEcACLSWsKIkdX .cluster-label span p{background-color:transparent;}#mermaid-svg-gSPEcACLSWsKIkdX .label text,#mermaid-svg-gSPEcACLSWsKIkdX span{fill:#333;color:#333;}#mermaid-svg-gSPEcACLSWsKIkdX .node rect,#mermaid-svg-gSPEcACLSWsKIkdX .node circle,#mermaid-svg-gSPEcACLSWsKIkdX .node ellipse,#mermaid-svg-gSPEcACLSWsKIkdX .node polygon,#mermaid-svg-gSPEcACLSWsKIkdX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gSPEcACLSWsKIkdX .rough-node .label text,#mermaid-svg-gSPEcACLSWsKIkdX .node .label text,#mermaid-svg-gSPEcACLSWsKIkdX .image-shape .label,#mermaid-svg-gSPEcACLSWsKIkdX .icon-shape .label{text-anchor:middle;}#mermaid-svg-gSPEcACLSWsKIkdX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gSPEcACLSWsKIkdX .rough-node .label,#mermaid-svg-gSPEcACLSWsKIkdX .node .label,#mermaid-svg-gSPEcACLSWsKIkdX .image-shape .label,#mermaid-svg-gSPEcACLSWsKIkdX .icon-shape .label{text-align:center;}#mermaid-svg-gSPEcACLSWsKIkdX .node.clickable{cursor:pointer;}#mermaid-svg-gSPEcACLSWsKIkdX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gSPEcACLSWsKIkdX .arrowheadPath{fill:#333333;}#mermaid-svg-gSPEcACLSWsKIkdX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gSPEcACLSWsKIkdX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gSPEcACLSWsKIkdX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gSPEcACLSWsKIkdX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gSPEcACLSWsKIkdX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gSPEcACLSWsKIkdX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gSPEcACLSWsKIkdX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gSPEcACLSWsKIkdX .cluster text{fill:#333;}#mermaid-svg-gSPEcACLSWsKIkdX .cluster span{color:#333;}#mermaid-svg-gSPEcACLSWsKIkdX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gSPEcACLSWsKIkdX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gSPEcACLSWsKIkdX rect.text{fill:none;stroke-width:0;}#mermaid-svg-gSPEcACLSWsKIkdX .icon-shape,#mermaid-svg-gSPEcACLSWsKIkdX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gSPEcACLSWsKIkdX .icon-shape p,#mermaid-svg-gSPEcACLSWsKIkdX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gSPEcACLSWsKIkdX .icon-shape .label rect,#mermaid-svg-gSPEcACLSWsKIkdX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gSPEcACLSWsKIkdX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gSPEcACLSWsKIkdX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gSPEcACLSWsKIkdX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 800 VUser时

响应时间突增




分析开始
查看响应时间图
发现异常?
定位问题事务

bank_do_transfer
查看服务器资源图
发现CPU飙升?
分析CPU热点
发现:转账服务

加密计算消耗大量CPU
💡 建议:优化加密算法

或增加应用服务器
查看数据库监控
发现慢查询?
分析慢查询日志
发现:转账流水表

缺少索引
💡 建议:添加复合索引

优化SQL语句
检查网络
💡 建议:检查网络带宽

和连接池配置

📝 测试报告摘要

markdown 复制代码
## 银行转账系统性能测试报告

### 测试结论:✅ 基本达标,有优化空间

| 测试项 | 目标 | 实际结果 | 状态 |
|--------|------|---------|------|
| 并发用户 | 1000 | 1000 | ✅ |
| 转账响应时间(95%) | < 3s | 2.1s | ✅ |
| 查询响应时间(95%) | < 1s | 0.6s | ✅ |
| TPS | >= 500 | 620 | ✅ |
| 错误率 | < 0.1% | 0.05% | ✅ |
| CPU使用率 | < 80% | 75% | ⚠️ |

### 发现的问题
1. 800 VUser 时 CPU 接近 80%,建议增加应用服务器
2. 转账流水表缺少索引,建议添加复合索引
3. Redis 缓存命中率仅 60%,建议优化缓存策略

### 优化建议
1. 增加 2 台应用服务器(水平扩展)
2. 为 transfer_record 表添加 (from_account, create_time) 复合索引
3. 调整 Redis 缓存过期策略,提高命中率到 90%+

第7章 常见问题与解决方案

7.1 脚本相关问题

🐛 问题1:录制不到请求

症状:点击录制后操作网页,VuGen 中没有任何请求记录

可能原因与解决方案
#mermaid-svg-mL27ZdkM5x8MWeYg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mL27ZdkM5x8MWeYg .error-icon{fill:#552222;}#mermaid-svg-mL27ZdkM5x8MWeYg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mL27ZdkM5x8MWeYg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mL27ZdkM5x8MWeYg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mL27ZdkM5x8MWeYg .marker.cross{stroke:#333333;}#mermaid-svg-mL27ZdkM5x8MWeYg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mL27ZdkM5x8MWeYg p{margin:0;}#mermaid-svg-mL27ZdkM5x8MWeYg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mL27ZdkM5x8MWeYg .cluster-label text{fill:#333;}#mermaid-svg-mL27ZdkM5x8MWeYg .cluster-label span{color:#333;}#mermaid-svg-mL27ZdkM5x8MWeYg .cluster-label span p{background-color:transparent;}#mermaid-svg-mL27ZdkM5x8MWeYg .label text,#mermaid-svg-mL27ZdkM5x8MWeYg span{fill:#333;color:#333;}#mermaid-svg-mL27ZdkM5x8MWeYg .node rect,#mermaid-svg-mL27ZdkM5x8MWeYg .node circle,#mermaid-svg-mL27ZdkM5x8MWeYg .node ellipse,#mermaid-svg-mL27ZdkM5x8MWeYg .node polygon,#mermaid-svg-mL27ZdkM5x8MWeYg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mL27ZdkM5x8MWeYg .rough-node .label text,#mermaid-svg-mL27ZdkM5x8MWeYg .node .label text,#mermaid-svg-mL27ZdkM5x8MWeYg .image-shape .label,#mermaid-svg-mL27ZdkM5x8MWeYg .icon-shape .label{text-anchor:middle;}#mermaid-svg-mL27ZdkM5x8MWeYg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mL27ZdkM5x8MWeYg .rough-node .label,#mermaid-svg-mL27ZdkM5x8MWeYg .node .label,#mermaid-svg-mL27ZdkM5x8MWeYg .image-shape .label,#mermaid-svg-mL27ZdkM5x8MWeYg .icon-shape .label{text-align:center;}#mermaid-svg-mL27ZdkM5x8MWeYg .node.clickable{cursor:pointer;}#mermaid-svg-mL27ZdkM5x8MWeYg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mL27ZdkM5x8MWeYg .arrowheadPath{fill:#333333;}#mermaid-svg-mL27ZdkM5x8MWeYg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mL27ZdkM5x8MWeYg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mL27ZdkM5x8MWeYg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mL27ZdkM5x8MWeYg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mL27ZdkM5x8MWeYg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mL27ZdkM5x8MWeYg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mL27ZdkM5x8MWeYg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mL27ZdkM5x8MWeYg .cluster text{fill:#333;}#mermaid-svg-mL27ZdkM5x8MWeYg .cluster span{color:#333;}#mermaid-svg-mL27ZdkM5x8MWeYg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mL27ZdkM5x8MWeYg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mL27ZdkM5x8MWeYg rect.text{fill:none;stroke-width:0;}#mermaid-svg-mL27ZdkM5x8MWeYg .icon-shape,#mermaid-svg-mL27ZdkM5x8MWeYg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mL27ZdkM5x8MWeYg .icon-shape p,#mermaid-svg-mL27ZdkM5x8MWeYg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mL27ZdkM5x8MWeYg .icon-shape .label rect,#mermaid-svg-mL27ZdkM5x8MWeYg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mL27ZdkM5x8MWeYg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mL27ZdkM5x8MWeYg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mL27ZdkM5x8MWeYg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 使用Chrome
使用IE
使用APP



录制不到请求
检查浏览器设置
确认安装了

VuGen浏览器扩展
确认IE版本兼容

建议用IE11
确认选择了

正确的协议

如Mobile HTTP
问题解决?
检查代理设置

端口是否被占用
问题解决?
尝试使用

Winsock录制模式
问题解决?
联系技术支持

🐛 问题2:回放失败

症状:脚本录制成功,但回放时所有事务都失败

常见原因

原因 现象 解决方案
关联缺失 服务器返回"会话过期" 添加关联,提取动态 Session ID
时间戳问题 请求被拒绝 参数化时间戳
SSL证书 SSL 错误 配置 SSL 设置,忽略证书验证
编码问题 中文乱码 设置正确的字符编码
思考时间 超时 调整超时时间设置

🐛 问题3:参数化不生效

症状:所有 VUser 仍然使用同一个值

解决方案

c 复制代码
// ❌ 错误:直接使用字符串
web_submit_data("login",
    ITEMDATA,
    "Name=username", "Value=zhangsan", ENDITEM,  // 写死了
    LAST);

// ✅ 正确:使用参数
web_submit_data("login",
    ITEMDATA,
    "Name=username", "Value={username}", ENDITEM,  // 使用花括号
    LAST);

// ✅ 如果需要用 C 变量,需要先 lr_save_string
char user[50] = "zhangsan";
lr_save_string(user, "username");
// 然后才能用 {username}

7.2 执行相关问题

🐛 问题4:VUser 无法启动

症状:Controller 中 VUser 状态显示 "Failed"

排查步骤
#mermaid-svg-wRfsECerrN9vADC1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wRfsECerrN9vADC1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wRfsECerrN9vADC1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wRfsECerrN9vADC1 .error-icon{fill:#552222;}#mermaid-svg-wRfsECerrN9vADC1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wRfsECerrN9vADC1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wRfsECerrN9vADC1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wRfsECerrN9vADC1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wRfsECerrN9vADC1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wRfsECerrN9vADC1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wRfsECerrN9vADC1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wRfsECerrN9vADC1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wRfsECerrN9vADC1 .marker.cross{stroke:#333333;}#mermaid-svg-wRfsECerrN9vADC1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wRfsECerrN9vADC1 p{margin:0;}#mermaid-svg-wRfsECerrN9vADC1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wRfsECerrN9vADC1 .cluster-label text{fill:#333;}#mermaid-svg-wRfsECerrN9vADC1 .cluster-label span{color:#333;}#mermaid-svg-wRfsECerrN9vADC1 .cluster-label span p{background-color:transparent;}#mermaid-svg-wRfsECerrN9vADC1 .label text,#mermaid-svg-wRfsECerrN9vADC1 span{fill:#333;color:#333;}#mermaid-svg-wRfsECerrN9vADC1 .node rect,#mermaid-svg-wRfsECerrN9vADC1 .node circle,#mermaid-svg-wRfsECerrN9vADC1 .node ellipse,#mermaid-svg-wRfsECerrN9vADC1 .node polygon,#mermaid-svg-wRfsECerrN9vADC1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wRfsECerrN9vADC1 .rough-node .label text,#mermaid-svg-wRfsECerrN9vADC1 .node .label text,#mermaid-svg-wRfsECerrN9vADC1 .image-shape .label,#mermaid-svg-wRfsECerrN9vADC1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-wRfsECerrN9vADC1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wRfsECerrN9vADC1 .rough-node .label,#mermaid-svg-wRfsECerrN9vADC1 .node .label,#mermaid-svg-wRfsECerrN9vADC1 .image-shape .label,#mermaid-svg-wRfsECerrN9vADC1 .icon-shape .label{text-align:center;}#mermaid-svg-wRfsECerrN9vADC1 .node.clickable{cursor:pointer;}#mermaid-svg-wRfsECerrN9vADC1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wRfsECerrN9vADC1 .arrowheadPath{fill:#333333;}#mermaid-svg-wRfsECerrN9vADC1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wRfsECerrN9vADC1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wRfsECerrN9vADC1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wRfsECerrN9vADC1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wRfsECerrN9vADC1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wRfsECerrN9vADC1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wRfsECerrN9vADC1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wRfsECerrN9vADC1 .cluster text{fill:#333;}#mermaid-svg-wRfsECerrN9vADC1 .cluster span{color:#333;}#mermaid-svg-wRfsECerrN9vADC1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wRfsECerrN9vADC1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wRfsECerrN9vADC1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-wRfsECerrN9vADC1 .icon-shape,#mermaid-svg-wRfsECerrN9vADC1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wRfsECerrN9vADC1 .icon-shape p,#mermaid-svg-wRfsECerrN9vADC1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wRfsECerrN9vADC1 .icon-shape .label rect,#mermaid-svg-wRfsECerrN9vADC1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wRfsECerrN9vADC1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wRfsECerrN9vADC1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wRfsECerrN9vADC1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} License不足
License正常
连接失败
连接正常
编译错误
编译正常
内存不足
资源正常
VUser启动失败
检查License
购买更多License

或减少VUser数
检查Load Generator
检查网络连接

防火墙设置
检查脚本
在VuGen中

重新编译脚本
检查系统资源
增加Load Generator

或减少VUser数
查看详细错误日志

lr_output_log

🐛 问题5:测试过程中响应时间突然变长

症状:测试前半段一切正常,后半段响应时间突然飙升

分析思路
#mermaid-svg-dBXUBpDcSSLuqBCi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dBXUBpDcSSLuqBCi .error-icon{fill:#552222;}#mermaid-svg-dBXUBpDcSSLuqBCi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dBXUBpDcSSLuqBCi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dBXUBpDcSSLuqBCi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dBXUBpDcSSLuqBCi .marker.cross{stroke:#333333;}#mermaid-svg-dBXUBpDcSSLuqBCi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dBXUBpDcSSLuqBCi p{margin:0;}#mermaid-svg-dBXUBpDcSSLuqBCi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-dBXUBpDcSSLuqBCi .cluster-label text{fill:#333;}#mermaid-svg-dBXUBpDcSSLuqBCi .cluster-label span{color:#333;}#mermaid-svg-dBXUBpDcSSLuqBCi .cluster-label span p{background-color:transparent;}#mermaid-svg-dBXUBpDcSSLuqBCi .label text,#mermaid-svg-dBXUBpDcSSLuqBCi span{fill:#333;color:#333;}#mermaid-svg-dBXUBpDcSSLuqBCi .node rect,#mermaid-svg-dBXUBpDcSSLuqBCi .node circle,#mermaid-svg-dBXUBpDcSSLuqBCi .node ellipse,#mermaid-svg-dBXUBpDcSSLuqBCi .node polygon,#mermaid-svg-dBXUBpDcSSLuqBCi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dBXUBpDcSSLuqBCi .rough-node .label text,#mermaid-svg-dBXUBpDcSSLuqBCi .node .label text,#mermaid-svg-dBXUBpDcSSLuqBCi .image-shape .label,#mermaid-svg-dBXUBpDcSSLuqBCi .icon-shape .label{text-anchor:middle;}#mermaid-svg-dBXUBpDcSSLuqBCi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dBXUBpDcSSLuqBCi .rough-node .label,#mermaid-svg-dBXUBpDcSSLuqBCi .node .label,#mermaid-svg-dBXUBpDcSSLuqBCi .image-shape .label,#mermaid-svg-dBXUBpDcSSLuqBCi .icon-shape .label{text-align:center;}#mermaid-svg-dBXUBpDcSSLuqBCi .node.clickable{cursor:pointer;}#mermaid-svg-dBXUBpDcSSLuqBCi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dBXUBpDcSSLuqBCi .arrowheadPath{fill:#333333;}#mermaid-svg-dBXUBpDcSSLuqBCi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dBXUBpDcSSLuqBCi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dBXUBpDcSSLuqBCi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dBXUBpDcSSLuqBCi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dBXUBpDcSSLuqBCi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dBXUBpDcSSLuqBCi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dBXUBpDcSSLuqBCi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dBXUBpDcSSLuqBCi .cluster text{fill:#333;}#mermaid-svg-dBXUBpDcSSLuqBCi .cluster span{color:#333;}#mermaid-svg-dBXUBpDcSSLuqBCi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dBXUBpDcSSLuqBCi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dBXUBpDcSSLuqBCi rect.text{fill:none;stroke-width:0;}#mermaid-svg-dBXUBpDcSSLuqBCi .icon-shape,#mermaid-svg-dBXUBpDcSSLuqBCi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dBXUBpDcSSLuqBCi .icon-shape p,#mermaid-svg-dBXUBpDcSSLuqBCi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dBXUBpDcSSLuqBCi .icon-shape .label rect,#mermaid-svg-dBXUBpDcSSLuqBCi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dBXUBpDcSSLuqBCi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dBXUBpDcSSLuqBCi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dBXUBpDcSSLuqBCi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 超过系统承载能力
并发数正常
CPU/内存飙升
资源正常
连接池满了
有慢查询
数据库正常
带宽打满
网络正常
响应时间突然变长
检查并发数
这是正常现象

找到了系统瓶颈
检查服务器资源
服务器资源瓶颈

需要优化或扩容
检查数据库
增加数据库连接池大小
优化SQL语句

添加索引
检查网络
增加网络带宽
检查应用是否有

内存泄漏


7.3 分析相关问题

🐛 问题6:图表数据为空

症状:Analysis 中打开图表,没有数据显示

解决方案

  1. 确认测试确实执行了(检查 Controller 日志)
  2. 确认场景执行时间超过 5 秒(太短可能没有数据)
  3. 确认 .lrr 结果文件没有损坏
  4. 尝试重新打开结果文件
  5. 检查过滤器设置是否过滤掉了所有数据

🐛 问题7:如何判断系统瓶颈

性能分析决策树
#mermaid-svg-XZsqn6yMZyc2QG1h{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XZsqn6yMZyc2QG1h .error-icon{fill:#552222;}#mermaid-svg-XZsqn6yMZyc2QG1h .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XZsqn6yMZyc2QG1h .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XZsqn6yMZyc2QG1h .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XZsqn6yMZyc2QG1h .marker.cross{stroke:#333333;}#mermaid-svg-XZsqn6yMZyc2QG1h svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XZsqn6yMZyc2QG1h p{margin:0;}#mermaid-svg-XZsqn6yMZyc2QG1h .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XZsqn6yMZyc2QG1h .cluster-label text{fill:#333;}#mermaid-svg-XZsqn6yMZyc2QG1h .cluster-label span{color:#333;}#mermaid-svg-XZsqn6yMZyc2QG1h .cluster-label span p{background-color:transparent;}#mermaid-svg-XZsqn6yMZyc2QG1h .label text,#mermaid-svg-XZsqn6yMZyc2QG1h span{fill:#333;color:#333;}#mermaid-svg-XZsqn6yMZyc2QG1h .node rect,#mermaid-svg-XZsqn6yMZyc2QG1h .node circle,#mermaid-svg-XZsqn6yMZyc2QG1h .node ellipse,#mermaid-svg-XZsqn6yMZyc2QG1h .node polygon,#mermaid-svg-XZsqn6yMZyc2QG1h .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XZsqn6yMZyc2QG1h .rough-node .label text,#mermaid-svg-XZsqn6yMZyc2QG1h .node .label text,#mermaid-svg-XZsqn6yMZyc2QG1h .image-shape .label,#mermaid-svg-XZsqn6yMZyc2QG1h .icon-shape .label{text-anchor:middle;}#mermaid-svg-XZsqn6yMZyc2QG1h .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XZsqn6yMZyc2QG1h .rough-node .label,#mermaid-svg-XZsqn6yMZyc2QG1h .node .label,#mermaid-svg-XZsqn6yMZyc2QG1h .image-shape .label,#mermaid-svg-XZsqn6yMZyc2QG1h .icon-shape .label{text-align:center;}#mermaid-svg-XZsqn6yMZyc2QG1h .node.clickable{cursor:pointer;}#mermaid-svg-XZsqn6yMZyc2QG1h .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XZsqn6yMZyc2QG1h .arrowheadPath{fill:#333333;}#mermaid-svg-XZsqn6yMZyc2QG1h .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XZsqn6yMZyc2QG1h .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XZsqn6yMZyc2QG1h .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XZsqn6yMZyc2QG1h .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XZsqn6yMZyc2QG1h .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XZsqn6yMZyc2QG1h .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XZsqn6yMZyc2QG1h .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XZsqn6yMZyc2QG1h .cluster text{fill:#333;}#mermaid-svg-XZsqn6yMZyc2QG1h .cluster span{color:#333;}#mermaid-svg-XZsqn6yMZyc2QG1h div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XZsqn6yMZyc2QG1h .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XZsqn6yMZyc2QG1h rect.text{fill:none;stroke-width:0;}#mermaid-svg-XZsqn6yMZyc2QG1h .icon-shape,#mermaid-svg-XZsqn6yMZyc2QG1h .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XZsqn6yMZyc2QG1h .icon-shape p,#mermaid-svg-XZsqn6yMZyc2QG1h .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XZsqn6yMZyc2QG1h .icon-shape .label rect,#mermaid-svg-XZsqn6yMZyc2QG1h .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XZsqn6yMZyc2QG1h .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XZsqn6yMZyc2QG1h .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XZsqn6yMZyc2QG1h :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否





CPU
内存
磁盘
网络
都正常
开始性能分析
查看 VUser 图
VUser 是否达到目标数?
License不足或

Load Generator不够
查看响应时间图
响应时间是否达标?
✅ 性能合格!
查看吞吐量图
吞吐量是否随VUser

线性增长?
瓶颈在服务器

继续分析
吞吐量达到天花板

找到系统极限
查看服务器资源图
哪个资源最高?
🔴 CPU瓶颈
🔴 内存瓶颈
🔴 I/O瓶颈
🔴 网络瓶颈
🔴 应用代码瓶颈


第8章 LoadRunner 与 CI/CD 集成

8.1 为什么需要 CI/CD 集成?

🎭 比喻:自动化流水线

手动性能测试就像手工打磨产品 ------每次都要人工操作,费时费力。CI/CD 集成就像建立自动化流水线------代码一提交,自动运行性能测试,发现问题自动报警。
#mermaid-svg-8fgVuBrjZtIp9Oro{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8fgVuBrjZtIp9Oro .error-icon{fill:#552222;}#mermaid-svg-8fgVuBrjZtIp9Oro .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8fgVuBrjZtIp9Oro .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8fgVuBrjZtIp9Oro .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8fgVuBrjZtIp9Oro .marker.cross{stroke:#333333;}#mermaid-svg-8fgVuBrjZtIp9Oro svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8fgVuBrjZtIp9Oro p{margin:0;}#mermaid-svg-8fgVuBrjZtIp9Oro .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8fgVuBrjZtIp9Oro .cluster-label text{fill:#333;}#mermaid-svg-8fgVuBrjZtIp9Oro .cluster-label span{color:#333;}#mermaid-svg-8fgVuBrjZtIp9Oro .cluster-label span p{background-color:transparent;}#mermaid-svg-8fgVuBrjZtIp9Oro .label text,#mermaid-svg-8fgVuBrjZtIp9Oro span{fill:#333;color:#333;}#mermaid-svg-8fgVuBrjZtIp9Oro .node rect,#mermaid-svg-8fgVuBrjZtIp9Oro .node circle,#mermaid-svg-8fgVuBrjZtIp9Oro .node ellipse,#mermaid-svg-8fgVuBrjZtIp9Oro .node polygon,#mermaid-svg-8fgVuBrjZtIp9Oro .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8fgVuBrjZtIp9Oro .rough-node .label text,#mermaid-svg-8fgVuBrjZtIp9Oro .node .label text,#mermaid-svg-8fgVuBrjZtIp9Oro .image-shape .label,#mermaid-svg-8fgVuBrjZtIp9Oro .icon-shape .label{text-anchor:middle;}#mermaid-svg-8fgVuBrjZtIp9Oro .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8fgVuBrjZtIp9Oro .rough-node .label,#mermaid-svg-8fgVuBrjZtIp9Oro .node .label,#mermaid-svg-8fgVuBrjZtIp9Oro .image-shape .label,#mermaid-svg-8fgVuBrjZtIp9Oro .icon-shape .label{text-align:center;}#mermaid-svg-8fgVuBrjZtIp9Oro .node.clickable{cursor:pointer;}#mermaid-svg-8fgVuBrjZtIp9Oro .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8fgVuBrjZtIp9Oro .arrowheadPath{fill:#333333;}#mermaid-svg-8fgVuBrjZtIp9Oro .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8fgVuBrjZtIp9Oro .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8fgVuBrjZtIp9Oro .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8fgVuBrjZtIp9Oro .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8fgVuBrjZtIp9Oro .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8fgVuBrjZtIp9Oro .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8fgVuBrjZtIp9Oro .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8fgVuBrjZtIp9Oro .cluster text{fill:#333;}#mermaid-svg-8fgVuBrjZtIp9Oro .cluster span{color:#333;}#mermaid-svg-8fgVuBrjZtIp9Oro div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8fgVuBrjZtIp9Oro .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8fgVuBrjZtIp9Oro rect.text{fill:none;stroke-width:0;}#mermaid-svg-8fgVuBrjZtIp9Oro .icon-shape,#mermaid-svg-8fgVuBrjZtIp9Oro .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8fgVuBrjZtIp9Oro .icon-shape p,#mermaid-svg-8fgVuBrjZtIp9Oro .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8fgVuBrjZtIp9Oro .icon-shape .label rect,#mermaid-svg-8fgVuBrjZtIp9Oro .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8fgVuBrjZtIp9Oro .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8fgVuBrjZtIp9Oro .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8fgVuBrjZtIp9Oro :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 有CI/CD集成
开发提交代码
自动触发流水线
自动部署测试环境
自动运行LoadRunner
自动分析结果
自动生成报告
自动通知团队
没有CI/CD集成
开发提交代码
手动部署测试环境
手动运行LoadRunner
手动分析结果
手动写报告
手动通知团队


8.2 集成架构

#mermaid-svg-qbpsAlsvxU8EbKLN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qbpsAlsvxU8EbKLN .error-icon{fill:#552222;}#mermaid-svg-qbpsAlsvxU8EbKLN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qbpsAlsvxU8EbKLN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qbpsAlsvxU8EbKLN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qbpsAlsvxU8EbKLN .marker.cross{stroke:#333333;}#mermaid-svg-qbpsAlsvxU8EbKLN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qbpsAlsvxU8EbKLN p{margin:0;}#mermaid-svg-qbpsAlsvxU8EbKLN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qbpsAlsvxU8EbKLN .cluster-label text{fill:#333;}#mermaid-svg-qbpsAlsvxU8EbKLN .cluster-label span{color:#333;}#mermaid-svg-qbpsAlsvxU8EbKLN .cluster-label span p{background-color:transparent;}#mermaid-svg-qbpsAlsvxU8EbKLN .label text,#mermaid-svg-qbpsAlsvxU8EbKLN span{fill:#333;color:#333;}#mermaid-svg-qbpsAlsvxU8EbKLN .node rect,#mermaid-svg-qbpsAlsvxU8EbKLN .node circle,#mermaid-svg-qbpsAlsvxU8EbKLN .node ellipse,#mermaid-svg-qbpsAlsvxU8EbKLN .node polygon,#mermaid-svg-qbpsAlsvxU8EbKLN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qbpsAlsvxU8EbKLN .rough-node .label text,#mermaid-svg-qbpsAlsvxU8EbKLN .node .label text,#mermaid-svg-qbpsAlsvxU8EbKLN .image-shape .label,#mermaid-svg-qbpsAlsvxU8EbKLN .icon-shape .label{text-anchor:middle;}#mermaid-svg-qbpsAlsvxU8EbKLN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qbpsAlsvxU8EbKLN .rough-node .label,#mermaid-svg-qbpsAlsvxU8EbKLN .node .label,#mermaid-svg-qbpsAlsvxU8EbKLN .image-shape .label,#mermaid-svg-qbpsAlsvxU8EbKLN .icon-shape .label{text-align:center;}#mermaid-svg-qbpsAlsvxU8EbKLN .node.clickable{cursor:pointer;}#mermaid-svg-qbpsAlsvxU8EbKLN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qbpsAlsvxU8EbKLN .arrowheadPath{fill:#333333;}#mermaid-svg-qbpsAlsvxU8EbKLN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qbpsAlsvxU8EbKLN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qbpsAlsvxU8EbKLN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qbpsAlsvxU8EbKLN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qbpsAlsvxU8EbKLN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qbpsAlsvxU8EbKLN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qbpsAlsvxU8EbKLN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qbpsAlsvxU8EbKLN .cluster text{fill:#333;}#mermaid-svg-qbpsAlsvxU8EbKLN .cluster span{color:#333;}#mermaid-svg-qbpsAlsvxU8EbKLN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qbpsAlsvxU8EbKLN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qbpsAlsvxU8EbKLN rect.text{fill:none;stroke-width:0;}#mermaid-svg-qbpsAlsvxU8EbKLN .icon-shape,#mermaid-svg-qbpsAlsvxU8EbKLN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qbpsAlsvxU8EbKLN .icon-shape p,#mermaid-svg-qbpsAlsvxU8EbKLN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qbpsAlsvxU8EbKLN .icon-shape .label rect,#mermaid-svg-qbpsAlsvxU8EbKLN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qbpsAlsvxU8EbKLN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qbpsAlsvxU8EbKLN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qbpsAlsvxU8EbKLN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} CI/CD 流水线
报告阶段
测试阶段
构建阶段
代码阶段
生成测试报告
开发提交代码

Git Push
CI Server

Jenkins/GitLab CI
自动构建

编译打包
自动部署

到测试环境
功能测试

自动化测试
性能测试

LoadRunner
安全测试

安全扫描
通知团队

Slack/邮件


8.3 使用命令行执行 LoadRunner

LoadRunner 提供了命令行工具,可以在 CI/CD 中调用:

📝 Controller 命令行执行

bash 复制代码
# ========== Windows 命令行执行场景 ==========

# 基本语法
"C:\Program Files\OpenText\LoadRunner\bin\wlrun.exe" ^
    -TestPath "C:\LR_Scenes\bank_transfer.lrs" ^
    -Run

# 带超时的执行
"C:\Program Files\OpenText\LoadRunner\bin\wlrun.exe" ^
    -TestPath "C:\LR_Scenes\bank_transfer.lrs" ^
    -Run ^
    -Timeout 3600

# 指定结果保存路径
"C:\Program Files\OpenText\LoadRunner\bin\wlrun.exe" ^
    -TestPath "C:\LR_Scenes\bank_transfer.lrs" ^
    -Run ^
    -ResultLocation "C:\LR_Results\run_20240115"

📝 VuGen 命令行执行

bash 复制代码
# ========== VuGen 命令行回放脚本 ==========

# 基本语法
"C:\Program Files\OpenText\LoadRunner\bin\mdrv.exe" ^
    -usr "C:\LR_Scripts\bank_transfer.usr" ^
    -out "C:\LR_Results\bank_transfer"

# 带迭代次数
"C:\Program Files\OpenText\LoadRunner\bin\mdrv.exe" ^
    -usr "C:\LR_Scripts\bank_transfer.usr" ^
    -out "C:\LR_Results\bank_transfer" ^
    -Iter 5

# 带参数文件
"C:\Program Files\OpenText\LoadRunner\bin\mdrv.exe" ^
    -usr "C:\LR_Scripts\bank_transfer.usr" ^
    -out "C:\LR_Results\bank_transfer" ^
    -paramfile "C:\LR_Data\bank_params.dat"

📝 Analysis 命令行生成报告

bash 复制代码
# ========== Analysis 命令行分析结果 ==========

# 生成 HTML 报告
"C:\Program Files\OpenText\LoadRunner\bin\analysis.exe" ^
    -template "C:\LR_Templates\summary_report.tpl" ^
    -input "C:\LR_Results\bank_transfer\bank_transfer.lrr" ^
    -output "C:\LR_Reports\bank_transfer_report.html"

8.4 Jenkins Pipeline 集成示例

groovy 复制代码
/*
 * ============================================
 * Jenkins Pipeline - LoadRunner 性能测试
 * ============================================
 */

pipeline {
    agent {
        label 'lr-controller'  // 指定运行在 LoadRunner Controller 机器上
    }

    triggers {
        // 每天晚上10点自动执行
        cron('0 22 * * *')
        // 也可以在代码合并到 main 分支时触发
        // GenericWebhook cause: branch == 'main'
    }

    environment {
        LR_HOME = 'C:\\Program Files\\OpenText\\LoadRunner'
        SCENE_PATH = 'C:\\LR_Scenes\\bank_transfer.lrs'
        RESULT_DIR = "C:\\LR_Results\\run_${BUILD_NUMBER}"
        REPORT_DIR = "C:\\LR_Reports\\run_${BUILD_NUMBER}"
    }

    stages {
        // ========== 阶段1:环境准备 ==========
        stage('环境准备') {
            steps {
                echo '开始准备测试环境...'
                // 检查测试环境是否可用
                bat '''
                    curl -s -o nul -w "%%{http_code}" http://bank-test.example.com/health
                '''
                // 清理上次的测试数据
                bat '''
                    if exist "%RESULT_DIR%" rmdir /s /q "%RESULT_DIR%"
                    mkdir "%RESULT_DIR%"
                '''
            }
        }

        // ========== 阶段2:执行性能测试 ==========
        stage('执行性能测试') {
            steps {
                echo '开始执行 LoadRunner 性能测试...'
                bat """
                    "%LR_HOME%\\bin\\wlrun.exe" ^
                        -TestPath "%SCENE_PATH%" ^
                        -Run ^
                        -ResultLocation "%RESULT_DIR%"
                """
            }
        }

        // ========== 阶段3:分析结果 ==========
        stage('分析结果') {
            steps {
                echo '开始分析测试结果...'
                // 使用 Analysis 生成报告
                bat """
                    "%LR_HOME%\\bin\\analysis.exe" ^
                        -input "%RESULT_DIR%\\bank_transfer.lrr" ^
                        -output "%REPORT_DIR%\\report.html"
                """
                // 解析结果,判断是否达标
                script {
                    // 读取关键指标
                    def responseTime = parseLrResult("${RESULT_DIR}")
                    def passed = responseTime <= 3000  // 3秒阈值

                    if (passed) {
                        currentBuild.result = 'SUCCESS'
                    } else {
                        currentBuild.result = 'UNSTABLE'
                    }
                }
            }
        }

        // ========== 阶段4:发送通知 ==========
        stage('发送通知') {
            steps {
                echo '发送测试报告通知...'
                // 发送邮件通知
                mail to: 'qa-team@example.com',
                    subject: "性能测试报告 #${BUILD_NUMBER} - ${currentBuild.result}",
                    body: """性能测试已完成!
                    构建号: ${BUILD_NUMBER}
                    状态: ${currentBuild.result}
                    报告: ${REPORT_DIR}\\report.html
                    """
            }
        }
    }

    post {
        always {
            // 归档测试结果
            archiveArtifacts artifacts: "${REPORT_DIR}/**/*", allowEmptyArchive: true
            // 在 Jenkins 页面展示报告
            publishHTML target: [
                reportDir: "${REPORT_DIR}",
                reportFiles: 'report.html',
                reportName: 'LoadRunner 性能测试报告',
                keepAll: true
            ]
        }
    }
}

8.5 LoadRunner Enterprise 与 DevOps 集成

🏗️ LoadRunner Enterprise 架构

#mermaid-svg-5DltC9psKgvbsTT8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5DltC9psKgvbsTT8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5DltC9psKgvbsTT8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5DltC9psKgvbsTT8 .error-icon{fill:#552222;}#mermaid-svg-5DltC9psKgvbsTT8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5DltC9psKgvbsTT8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5DltC9psKgvbsTT8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5DltC9psKgvbsTT8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5DltC9psKgvbsTT8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5DltC9psKgvbsTT8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5DltC9psKgvbsTT8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5DltC9psKgvbsTT8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5DltC9psKgvbsTT8 .marker.cross{stroke:#333333;}#mermaid-svg-5DltC9psKgvbsTT8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5DltC9psKgvbsTT8 p{margin:0;}#mermaid-svg-5DltC9psKgvbsTT8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5DltC9psKgvbsTT8 .cluster-label text{fill:#333;}#mermaid-svg-5DltC9psKgvbsTT8 .cluster-label span{color:#333;}#mermaid-svg-5DltC9psKgvbsTT8 .cluster-label span p{background-color:transparent;}#mermaid-svg-5DltC9psKgvbsTT8 .label text,#mermaid-svg-5DltC9psKgvbsTT8 span{fill:#333;color:#333;}#mermaid-svg-5DltC9psKgvbsTT8 .node rect,#mermaid-svg-5DltC9psKgvbsTT8 .node circle,#mermaid-svg-5DltC9psKgvbsTT8 .node ellipse,#mermaid-svg-5DltC9psKgvbsTT8 .node polygon,#mermaid-svg-5DltC9psKgvbsTT8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5DltC9psKgvbsTT8 .rough-node .label text,#mermaid-svg-5DltC9psKgvbsTT8 .node .label text,#mermaid-svg-5DltC9psKgvbsTT8 .image-shape .label,#mermaid-svg-5DltC9psKgvbsTT8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-5DltC9psKgvbsTT8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5DltC9psKgvbsTT8 .rough-node .label,#mermaid-svg-5DltC9psKgvbsTT8 .node .label,#mermaid-svg-5DltC9psKgvbsTT8 .image-shape .label,#mermaid-svg-5DltC9psKgvbsTT8 .icon-shape .label{text-align:center;}#mermaid-svg-5DltC9psKgvbsTT8 .node.clickable{cursor:pointer;}#mermaid-svg-5DltC9psKgvbsTT8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5DltC9psKgvbsTT8 .arrowheadPath{fill:#333333;}#mermaid-svg-5DltC9psKgvbsTT8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5DltC9psKgvbsTT8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5DltC9psKgvbsTT8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5DltC9psKgvbsTT8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5DltC9psKgvbsTT8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5DltC9psKgvbsTT8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5DltC9psKgvbsTT8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5DltC9psKgvbsTT8 .cluster text{fill:#333;}#mermaid-svg-5DltC9psKgvbsTT8 .cluster span{color:#333;}#mermaid-svg-5DltC9psKgvbsTT8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5DltC9psKgvbsTT8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5DltC9psKgvbsTT8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-5DltC9psKgvbsTT8 .icon-shape,#mermaid-svg-5DltC9psKgvbsTT8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5DltC9psKgvbsTT8 .icon-shape p,#mermaid-svg-5DltC9psKgvbsTT8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5DltC9psKgvbsTT8 .icon-shape .label rect,#mermaid-svg-5DltC9psKgvbsTT8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5DltC9psKgvbsTT8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5DltC9psKgvbsTT8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5DltC9psKgvbsTT8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} DevOps 工具链
LoadRunner Enterprise (SaaS/On-Premise)
存储
引擎
Web 界面
LoadRunner Enterprise

Web 门户
负载引擎 1

云端/本地
负载引擎 2

云端/本地
负载引擎 N

云端/本地
结果数据库
脚本仓库
Git/GitHub
Jenkins
Slack
Jira

📝 REST API 集成

bash 复制代码
# ========== LoadRunner Enterprise REST API ==========

# 1. 认证获取 Token
curl -X POST "https://lr-enterprise.example.com/rest/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"password"}'

# 2. 上传脚本
curl -X POST "https://lr-enterprise.example.com/rest/v1/scripts" \
  -H "Authorization: Bearer {token}" \
  -F "file=@bank_transfer.zip"

# 3. 创建测试
curl -X POST "https://lr-enterprise.example.com/rest/v1/tests" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Bank Transfer Performance Test",
    "scriptId": 123,
    "vusers": 1000,
    "duration": 1800,
    "rampUp": 300
  }'

# 4. 执行测试
curl -X POST "https://lr-enterprise.example.com/rest/v1/tests/123/runs" \
  -H "Authorization: Bearer {token}"

# 5. 获取测试结果
curl -X GET "https://lr-enterprise.example.com/rest/v1/tests/123/runs/456/results" \
  -H "Authorization: Bearer {token}"

8.6 最佳实践

✅ CI/CD 集成最佳实践

#mermaid-svg-AynpNIJkE3ac72ns{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AynpNIJkE3ac72ns .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AynpNIJkE3ac72ns .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AynpNIJkE3ac72ns .error-icon{fill:#552222;}#mermaid-svg-AynpNIJkE3ac72ns .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AynpNIJkE3ac72ns .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AynpNIJkE3ac72ns .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AynpNIJkE3ac72ns .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AynpNIJkE3ac72ns .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AynpNIJkE3ac72ns .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AynpNIJkE3ac72ns .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AynpNIJkE3ac72ns .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AynpNIJkE3ac72ns .marker.cross{stroke:#333333;}#mermaid-svg-AynpNIJkE3ac72ns svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AynpNIJkE3ac72ns p{margin:0;}#mermaid-svg-AynpNIJkE3ac72ns .edge{stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .section--1 rect,#mermaid-svg-AynpNIJkE3ac72ns .section--1 path,#mermaid-svg-AynpNIJkE3ac72ns .section--1 circle,#mermaid-svg-AynpNIJkE3ac72ns .section--1 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section--1 text{fill:#ffffff;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth--1{stroke-width:17;}#mermaid-svg-AynpNIJkE3ac72ns .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-0 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-0 path,#mermaid-svg-AynpNIJkE3ac72ns .section-0 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-0 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-AynpNIJkE3ac72ns .section-0 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-0{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-0{stroke-width:14;}#mermaid-svg-AynpNIJkE3ac72ns .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-1 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-1 path,#mermaid-svg-AynpNIJkE3ac72ns .section-1 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-1 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-1 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-1{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-1{stroke-width:11;}#mermaid-svg-AynpNIJkE3ac72ns .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-2 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-2 path,#mermaid-svg-AynpNIJkE3ac72ns .section-2 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-2 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-2 text{fill:#ffffff;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-2{stroke-width:8;}#mermaid-svg-AynpNIJkE3ac72ns .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-3 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-3 path,#mermaid-svg-AynpNIJkE3ac72ns .section-3 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-3 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-3 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-3{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-3{stroke-width:5;}#mermaid-svg-AynpNIJkE3ac72ns .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-4 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-4 path,#mermaid-svg-AynpNIJkE3ac72ns .section-4 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-4 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-4 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-4{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-4{stroke-width:2;}#mermaid-svg-AynpNIJkE3ac72ns .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-5 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-5 path,#mermaid-svg-AynpNIJkE3ac72ns .section-5 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-5 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-5 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-5{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-5{stroke-width:-1;}#mermaid-svg-AynpNIJkE3ac72ns .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-6 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-6 path,#mermaid-svg-AynpNIJkE3ac72ns .section-6 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-6 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-6 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-6{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-6{stroke-width:-4;}#mermaid-svg-AynpNIJkE3ac72ns .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-7 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-7 path,#mermaid-svg-AynpNIJkE3ac72ns .section-7 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-7 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-7 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-7{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-7{stroke-width:-7;}#mermaid-svg-AynpNIJkE3ac72ns .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-8 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-8 path,#mermaid-svg-AynpNIJkE3ac72ns .section-8 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-8 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-8 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-8{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-8{stroke-width:-10;}#mermaid-svg-AynpNIJkE3ac72ns .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-9 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-9 path,#mermaid-svg-AynpNIJkE3ac72ns .section-9 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-9 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-9 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-9{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-9{stroke-width:-13;}#mermaid-svg-AynpNIJkE3ac72ns .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-10 rect,#mermaid-svg-AynpNIJkE3ac72ns .section-10 path,#mermaid-svg-AynpNIJkE3ac72ns .section-10 circle,#mermaid-svg-AynpNIJkE3ac72ns .section-10 polygon,#mermaid-svg-AynpNIJkE3ac72ns .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-10 text{fill:black;}#mermaid-svg-AynpNIJkE3ac72ns .node-icon-10{font-size:40px;color:black;}#mermaid-svg-AynpNIJkE3ac72ns .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .edge-depth-10{stroke-width:-16;}#mermaid-svg-AynpNIJkE3ac72ns .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-AynpNIJkE3ac72ns .disabled,#mermaid-svg-AynpNIJkE3ac72ns .disabled circle,#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:lightgray;}#mermaid-svg-AynpNIJkE3ac72ns .disabled text{fill:#efefef;}#mermaid-svg-AynpNIJkE3ac72ns .section-root rect,#mermaid-svg-AynpNIJkE3ac72ns .section-root path,#mermaid-svg-AynpNIJkE3ac72ns .section-root circle,#mermaid-svg-AynpNIJkE3ac72ns .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-AynpNIJkE3ac72ns .section-root text{fill:#ffffff;}#mermaid-svg-AynpNIJkE3ac72ns .section-root span{color:#ffffff;}#mermaid-svg-AynpNIJkE3ac72ns .section-2 span{color:#ffffff;}#mermaid-svg-AynpNIJkE3ac72ns .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-AynpNIJkE3ac72ns .edge{fill:none;}#mermaid-svg-AynpNIJkE3ac72ns .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-AynpNIJkE3ac72ns :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} CI/CD集成

最佳实践
脚本管理
脚本纳入版本控制Git
使用参数化适应不同环境
定期维护和更新脚本
执行策略
代码合并后自动触发
设置合理的超时时间
失败自动重试一次
结果管理
自动生成HTML报告
关键指标设阈值
历史结果趋势对比
通知机制
测试完成自动通知
性能退化立即报警
定期发送性能摘要
资源管理
测试环境隔离
测试数据自动准备/清理
License资源池化管理

📋 性能门禁(Performance Gates)

c 复制代码
/*
 * ============================================
 * 性能门禁设置示例
 * 在 Jenkins Pipeline 中设置性能阈值
 * ============================================
 *
 * 门禁规则:
 * 1. 平均响应时间 < 3秒
 * 2. 95%响应时间 < 5秒
 * 3. 错误率 < 0.1%
 * 4. TPS >= 500
 * 5. CPU使用率 < 80%
 *
 * 任一规则不满足 → 构建标记为 UNSTABLE
 * 超过2条规则不满足 → 构建标记为 FAILURE
 */

// Jenkins Pipeline 中的性能门禁示例
def checkPerformanceGate(results) {
    int violations = 0

    if (results.avgResponseTime > 3000) {
        echo "❌ 违规:平均响应时间 ${results.avgResponseTime}ms > 3000ms"
        violations++
    }

    if (results.p95ResponseTime > 5000) {
        echo "❌ 违规:95%响应时间 ${results.p95ResponseTime}ms > 5000ms"
        violations++
    }

    if (results.errorRate > 0.001) {
        echo "❌ 违规:错误率 ${results.errorRate} > 0.1%"
        violations++
    }

    if (results.tps < 500) {
        echo "❌ 违规:TPS ${results.tps} < 500"
        violations++
    }

    if (violations >= 2) {
        currentBuild.result = 'FAILURE'
        echo "🔴 性能门禁失败!${violations} 条规则违反"
    } else if (violations > 0) {
        currentBuild.result = 'UNSTABLE'
        echo "⚠️ 性能门禁警告!${violations} 条规则违反"
    } else {
        echo "✅ 性能门禁通过!所有指标达标"
    }
}

📚 附录

A. LoadRunner 快捷键

快捷键 功能
Ctrl+Alt+R 开始录制
Ctrl+Alt+S 停止录制
F5 回放脚本
Ctrl+F5 编译脚本
Ctrl+Shift+L 参数化选中值
Ctrl+Shift+C 添加注释
Ctrl+M 添加事务
Ctrl+B 添加集合点

B. 常用 LoadRunner 函数速查

函数 说明 示例
lr_start_transaction 开始事务 lr_start_transaction("login")
lr_end_transaction 结束事务 lr_end_transaction("login", LR_AUTO)
lr_think_time 思考时间 lr_think_time(3)
lr_output_message 输出日志 lr_output_message("test")
lr_save_string 保存字符串到参数 lr_save_string("value", "param")
lr_eval_string 获取参数值 lr_eval_string("{param}")
lr_random 随机数 lr_random(1, 100)
lr_rendezvous 集合点 lr_rendezvous("peak")
web_reg_save_param 关联(文本) 见关联章节
web_reg_save_param_json 关联(JSON) 见关联章节
web_reg_find 文本检查点 web_reg_find("Text=success")
web_url GET 请求 见脚本示例
web_submit_data POST 表单 见脚本示例
web_custom_request 自定义请求 见脚本示例

C. 性能测试术语表

术语 英文 解释
并发用户数 Concurrent Users 同时向系统发送请求的用户数
响应时间 Response Time 从发送请求到收到响应的时间
吞吐量 Throughput 单位时间内系统处理的请求数
TPS Transactions Per Second 每秒处理的事务数
90%线 90th Percentile 90%的请求在此时间内完成
P95 95th Percentile 95%的请求在此时间内完成
基准测试 Baseline Test 建立性能基准的测试
负载测试 Load Test 模拟预期负载的测试
压力测试 Stress Test 超出预期负载的测试
稳定性测试 Endurance Test 长时间运行的测试
容量测试 Capacity Test 找到系统最大容量的测试
瓶颈 Bottleneck 限制系统性能的薄弱环节

记住:工具只是手段,理解性能测试的思路和方法才是核心!