第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 中打开图表,没有数据显示
解决方案:
- 确认测试确实执行了(检查 Controller 日志)
- 确认场景执行时间超过 5 秒(太短可能没有数据)
- 确认
.lrr结果文件没有损坏 - 尝试重新打开结果文件
- 检查过滤器设置是否过滤掉了所有数据
🐛 问题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 | 限制系统性能的薄弱环节 |
记住:工具只是手段,理解性能测试的思路和方法才是核心!