1. 项目概述:为什么LoadRunner依然是性能测试的“老炮儿”
在软件交付节奏越来越快的今天,性能问题就像一颗不定时炸弹,随时可能在用户量激增时引爆。我见过太多项目,功能测试一切顺利,一上线就卡顿、崩溃,最终导致用户流失和商业损失。这时候,一个靠谱的性能测试工具就成了技术团队的“压舱石”。提到性能测试,LoadRunner这个名字绝对绕不开。尽管现在有JMeter、Gatling等一众后起之秀,但LoadRunner在复杂企业级应用、协议支持深度和结果分析能力上,依然有着不可替代的地位。很多金融、电信、大型电商的核心系统性能压测,LoadRunner还是首选方案。
这个教程,就是为你准备的。无论你是刚接触性能测试的新手,还是想系统掌握LoadRunner这套重型武器的测试工程师,我都会带你从零开始,拆解它的每一个核心部件。我们不止讲怎么点按钮,更要讲清楚每个操作背后的逻辑:为什么脚本要这样录制?场景设计时思考的维度是什么?那些复杂的监控图表到底说明了什么问题?我会把我这些年趟过的坑、总结的技巧,毫无保留地分享出来。我们的目标很明确:让你不仅能跑起来一个测试,更能看懂测试结果,定位性能瓶颈,提出有价值的优化建议。
2. LoadRunner核心组件与工作流全解析
在动手之前,我们必须先理解LoadRunner的“五脏六腑”。它不是一个单一软件,而是一套由多个工具组成的套件,各司其职,共同完成从脚本创建到报告生成的完整流程。理解这个架构,是高效使用它的前提。
2.1 三大核心组件:各司其职的黄金三角
LoadRunner的经典架构主要由三部分组成:Virtual User Generator (VuGen)、Controller和Analysis。你可以把它们想象成电影制作团队。
Virtual User Generator (VuGen) - 编剧与演员培训:这是脚本开发环境。它的核心工作是“录制”和“增强”用户操作。比如,你打开一个购物网站,点击商品,加入购物车,登录,支付。VuGen会像摄像机一样录下你和服务器之间的所有网络对话(HTTP请求),并生成一个脚本。但这个原始脚本就像个只会念台词的机器人,我们需要对它进行“培训”和“增强”,比如教它如何参数化(让不同虚拟用户使用不同的账号登录)、如何检查关键步骤是否成功(比如检查“支付成功”的页面是否出现)、如何模拟思考时间(用户操作间的停顿)。VuGen支持上百种协议,从最常见的Web(HTTP/HTML)到Socket、数据库、中间件协议,这是它强大的根基。
Controller - 总导演与场控:脚本写好之后,谁来指挥成千上万个“虚拟演员”(Vuser)上场表演呢?就是Controller。它是负载测试的控制中心。在这里,你设计测试场景(Scenario):安排多少用户、以什么节奏(是同时启动还是分批递增)运行、运行多长时间、目标服务器是哪些。Controller还负责管理负载生成器(Load Generator),这些负载生成器才是真正执行脚本、产生压力的“机器”。你可以用一台Controller控制分布在多台机器上的负载生成器,模拟来自不同网络区域的巨大压力。Controller同时还是一个实时监控面板,在测试运行时,你可以看到实时的用户数、事务响应时间、每秒点击量、服务器资源(CPU、内存)等关键指标。
Analysis - 影评人与数据分析师:测试跑完了,产生了一大堆原始数据。Analysis工具的任务就是把这些数据变成有意义的洞察。它能生成丰富的图表和报告,帮你分析:系统的最大并发用户支撑能力是多少?哪个事务的响应时间最慢?在压力下服务器的资源瓶颈出现在哪里(是CPU先到100%,还是内存先耗尽)?它可以通过合并多次运行的结果进行对比分析,也能自动定位一些常见瓶颈。一份专业的Analysis报告,是向开发团队和领导汇报性能状况、推动优化最有力的证据。
2.2 性能测试标准工作流:从规划到报告
理解了组件,我们来看它们如何串联。一个完整的性能测试流程,通常遵循以下步骤,这不仅是LoadRunner的流程,也是性能测试的通用方法论:
计划与需求分析:这是最容易忽略却最关键的一步。要测什么?目标是啥?是评估系统能否支撑“双十一”的10000用户并发,还是找出系统在持续压力下的稳定性问题?需要定义清楚要测试的业务场景(如登录、搜索、下单)、性能指标(如登录响应时间<2秒,95%的用户)、测试环境配置等。没有明确目标的性能测试,就是漫无目的的“放火”。
脚本开发与增强(VuGen):根据选定的业务场景,使用VuGen录制脚本。录制只是开始,更重要的是脚本增强,使其能真实、有效地模拟用户行为。这部分我们会在下一章详细展开。
场景设计与执行(Controller):将增强后的脚本放入Controller,设计负载模型。比如,使用“目标场景”模式(设定一个目标,如每秒完成50个事务,让工具自动调节用户数去达成),或更常用的“手工场景”模式(手动设定用户加载策略,如每15秒启动5个用户,持续运行10分钟)。配置需要监控的服务器计数器(如Windows性能计数器、Linux的
top命令输出等)。然后,运行场景,实时观察。监控与问题排查(Controller运行时):测试执行中,通过Controller的监控图表观察系统状态。如果发现错误率飙升或响应时间异常增长,可能需要及时停止,检查脚本或被测系统环境是否存在问题。
结果分析与报告(Analysis):测试结束后,使用Analysis打开结果文件,进行深入分析。识别性能瓶颈(是网络、服务器、数据库还是应用代码),对比不同版本或配置下的性能差异,最终形成结论清晰的测试报告。
注意:千万别跳过第一步“计划与需求分析”。我见过很多团队一上来就录脚本、加压,结果测出来的数据谁也说不清代表什么,也无法回答“系统到底行不行”这个核心问题。花30%的时间在计划上,能让后续70%的工作价值翻倍。
3. 脚本开发实战:从录制到增强的完整过程
脚本是性能测试的基石,一个糟糕的脚本会导致测试结果完全失真。这一章,我们以最常见的Web(HTTP/HTML)协议为例,手把手走一遍脚本开发的全流程,并深入每个增强点背后的原理。
3.1 录制脚本:捕获真实的用户会话
打开VuGen,创建一个新的“Web - HTTP/HTML”协议脚本。在录制选项中,你需要关注几个关键点:
- 应用程序类型:现在绝大多数都是基于浏览器的Web应用,选择“Internet Applications”即可。如果是测试像QQ那样的桌面客户端内部通信,可能需要选择“WinSocket”等协议。
- 录制动作:选择“录制”后,VuGen会启动指定的浏览器(如IE或Chrome,需注意版本兼容性)。此时,你在浏览器中的所有操作,与服务器之间的HTTP请求和响应,都会被VuGen捕获。
- URL地址:填入被测系统的起始地址。
- 录制到操作:建议选择“Action”。这是VuGen脚本的逻辑划分单位。通常,我们把初始化操作(如打开首页)放在
vuser_init部分(只运行一次),把核心的业务操作(如登录、查询)放在Action部分(会反复运行),把清理操作(如退出登录)放在vuser_end部分(只运行一次)。
录制一个简单的流程:访问首页 -> 输入用户名密码登录 -> 进入主页面。停止录制后,VuGen会自动生成一个包含大量web_url,web_submit_data等函数的脚本。但此时生成的脚本是“死的”,直接回放可能失败,也无法模拟多用户。
3.2 脚本参数化:让虚拟用户“活”起来
如果1000个虚拟用户都用同一个账号“test/user123”去登录,服务器端可能会因为重复登录而报错,或者缓存导致测试数据不真实。参数化就是为了解决这个问题。
操作步骤:
- 在脚本中找到登录请求中的用户名和密码值(如
web_submit_data函数中的"Name=username", "Value=test",)。 - 选中
"test",右键选择“Replace with a Parameter”。 - 给参数命名,如
username。 - 在参数列表中,选择参数类型。最常用的是“File”。点击“创建表”,手动添加多行数据,如
user1, user2, ... user1000,以及对应的密码pass1, pass2, ...。也可以选择“导入”一个已准备好的CSV或TXT文件。 - 设置参数的更新方式:
- 每次迭代更新:每个虚拟用户在每次循环
Action时,取一个新值。这是最常用的方式。 - 每次出现更新:每次遇到该参数就更新。
- 仅一次:整个场景运行期间,每个虚拟用户只取一次值。
- 每次迭代更新:每个虚拟用户在每次循环
- 设置数据分配方式:
- 顺序(Sequential):按顺序取,用完从头开始。
- 随机(Random):随机从文件中选取。
- 唯一(Unique):每个Vuser分配一个唯一值,确保不重复。当测试需要大量独立数据时(如注册),必须选择此项,并确保数据量足够。
为什么这么做?参数化不仅避免了数据冲突,更重要的是模拟了真实世界中不同用户使用不同数据的场景,使得测试对服务器缓存、数据库查询、会话处理等环节的压力更贴近实际。
3.3 插入事务与检查点:定义成功与度量性能
事务(Transaction):用来度量一个或多个操作的响应时间。比如,我们把“登录”这个操作定义为一个事务。
操作步骤:
- 在登录操作开始前,插入开始事务标记:
lr_start_transaction("Login"); - 在登录操作结束后(通常是在收到登录成功响应后),插入结束事务标记:
lr_end_transaction("Login", LR_AUTO);LR_AUTO表示由LoadRunner自动判断事务状态(成功/失败)。你也可以手动指定LR_PASS或LR_FAIL。
检查点(Checkpoint):用于验证请求是否成功完成。比如,登录后页面会显示“欢迎,[用户名]”,我们可以检查这个文本是否出现,来判断登录是否成功。
操作步骤:
- 在登录请求(如
web_submit_data)之后,插入文本检查函数:web_reg_find("Text=欢迎", "SaveCount=login_count", LAST);- 这个函数是“注册型”函数,必须放在它要检查的请求之前。
"SaveCount=login_count"会将匹配到的次数保存到变量login_count中。
- 在请求之后,可以添加判断:
if (atoi(lr_eval_string("{login_count}")) > 0) { lr_end_transaction("Login", LR_PASS); } else { lr_end_transaction("Login", LR_FAIL); }。这样,事务的状态就由检查点结果决定了。
实操心得:事务的划分要基于业务逻辑。一个常见的误区是把整个脚本包在一个大事务里。应该根据用户感知,将关键业务步骤(如“加入购物车”、“提交订单”、“支付”)分别设为独立的事务,这样在分析时才能精准定位是哪个环节慢。
3.4 关联(Correlation):处理动态数据
这是脚本开发中最具挑战性的一步。很多Web应用会使用动态的Session ID、Token、ViewState等值,这些值在每次会话中都不同。录制时,这些值被硬编码在脚本里;回放时,服务器返回新的值,脚本如果还用旧值去请求,必然失败。
关联的本质:从服务器响应中提取动态值,保存为参数,并在后续请求中自动替换这个参数。
LoadRunner提供两种主要方式:
- 自动关联:VuGen可以扫描脚本,对比录制和回放时的服务器响应,自动找出可能需要进行关联的动态值。在回放脚本后,如果失败,可以尝试使用“Scan for Correlation”功能。但自动关联并非万能,复杂场景下识别率有限。
- 手动关联(必须掌握):这是核心技能。步骤如下:
- 找到需要关联的数据:对比录制时的脚本和回放时的日志(在回放日志中搜索“not found”、“invalid”等错误信息,找到哪个参数值失效了)。
- 找到这个值的来源:在录制日志中,找到这个值最初是从哪个服务器响应中返回的。通常是一个
web_reg_save_param函数(如果是录制时自动处理的)或者在一个响应包体中。 - 编写关联函数:在接收到该响应的请求之前,插入关联函数。最常用的是
web_reg_save_param_ex(功能更强大)。例如,假设服务器在登录前返回一个token: “abc123”。web_reg_save_param_ex( "ParamName=CorrToken", "LB=token: \"", "RB=\"", SEARCH_FILTERS, "Scope=Body", LAST);LB和RB是左边界和右边界,用于精确定位要提取的文本。
- 替换脚本中的硬编码值:在后续需要用到该
token的请求中,将原来的硬编码值"abc123"替换为参数{CorrToken}。
踩坑记录:关联的边界(LB/RB)选择至关重要。要选择能唯一标识该动态值的前后文本,且这些文本本身在每次响应中是不变的。如果边界文本也动态变化,关联就会失败。有时需要结合正则表达式来定义更灵活的边界。
3.5 添加思考时间与集合点:模拟真实用户节奏
思考时间(Think Time):真实用户操作之间会有停顿,比如浏览商品详情、阅读信息。思考时间模拟了这个停顿,使负载曲线更平滑、真实。在脚本中,使用lr_think_time()函数添加,如lr_think_time(5);表示暂停5秒。在Controller设计场景时,可以选择是否忽略思考时间。在“探索系统极限”的负载测试中,通常会忽略思考时间以产生最大压力;在“模拟真实用户行为”的稳定性测试中,则需要启用思考时间。
集合点(Rendezvous):用于模拟“瞬间并发”的场景。比如,秒杀活动开始的那一刻,成千上万的用户同时点击“立即购买”。在脚本中购买操作前插入lr_rendezvous("Buy_Spike");。在Controller中,可以设置集合点策略,让到达集合点的虚拟用户等待,直到达到指定数量或条件后同时释放,产生爆发性压力。
4. 场景设计与执行:构建真实的压力模型
脚本准备就绪后,我们进入Controller,开始设计并运行负载测试场景。这是将脚本转化为实际压力的关键步骤。
4.1 手工场景 vs. 目标场景
手工场景:这是最常用、最灵活的模式。你完全手动控制虚拟用户的数量、加载方式和运行时间。你需要定义“计划(Schedule)”。
- 初始化:虚拟用户以何种方式初始化(同时初始化可能对启动机器造成压力,通常选择每隔一段时间初始化一部分)。
- 启动(Start Vusers):定义用户加载策略,例如“每15秒启动2个Vuser”,直到达到总用户数。
- 持续时间(Duration):压力保持稳定运行的时间,例如30分钟。这是观察系统在稳定压力下表现的关键阶段。
- 停止(Stop Vusers):如何停止用户,例如“每30秒停止5个Vuser”。
目标场景:你设定一个测试目标(例如,每秒完成10个“登录”事务,或平均事务响应时间低于3秒),LoadRunner会自动调整虚拟用户的数量来尝试达到这个目标。这种模式适用于验证系统是否能满足特定的性能指标要求。
4.2 配置负载生成器与监控
负载生成器(Load Generator):如果你的测试需要模拟成百上千的用户,单台机器可能无法产生足够的压力或网络连接。你需要配置额外的负载生成器。在Controller的“负载生成器”列表中,添加其他机器的IP地址,并确保那台机器上安装了Load Generator服务且已启动。这样,压力就可以分布式地产生。
监控(Monitors):这是性能测试的眼睛。Controller可以实时监控两类资源:
- 被测系统资源:这是最重要的。你需要添加对被测服务器(Web服务器、应用服务器、数据库服务器)的监控。对于Windows服务器,可以添加“Windows Resources”监控,输入服务器IP和管理员凭据,选择要监控的计数器(如
% Processor Time,Available MBytes,Disk Read/sec等)。对于Linux服务器,通常需要在服务器上启动rstatd或ssh服务,Controller通过它来获取top,vmstat等命令的输出。 - 运行监控:Controller自身提供的图表,如“运行Vuser数”、“每秒点击量”、“吞吐量”、“事务响应时间”等。这些图表在运行时实时更新,是判断测试是否正常进行的第一手资料。
实操要点:监控不是越多越好。添加过多计数器会影响负载生成器自身的性能。只添加与性能瓶颈分析最相关的计数器:CPU、内存、磁盘I/O、网络带宽,以及与应用相关的计数器(如JVM的堆内存使用率、数据库的连接数、缓存命中率等)。
4.3 场景运行策略与实时诊断
点击“开始场景”后,进入运行界面。这里有几个关键视图:
- 场景组:查看各个脚本的Vuser状态(就绪、运行中、完成、错误)。
- 图表:重点关注“运行Vuser”、“事务响应时间”、“每秒点击量”、“吞吐量”和“错误”这五个图。将它们合并查看,可以快速发现关联性。例如,当Vuser数上升时,响应时间是否同步急剧上升?错误数是否开始出现?
- 输出窗口:查看每个Vuser的详细日志,对于调试脚本错误至关重要。
如果测试过程中发现错误率突然升高(例如,超过1%),或者关键事务的响应时间远超预期,不要盲目等到场景结束。应该及时停止场景,通过错误信息和日志初步判断原因。常见原因包括:被测系统崩溃、中间件连接池耗尽、数据库锁死、或者脚本本身因未处理好的动态数据而大面积失败。
5. 深度结果分析:从数据图表到性能瓶颈定位
测试执行完毕,我们得到了一个结果目录。用Analysis打开它,海量数据将呈现在我们面前。分析的目标是从这些数据中提炼出关于系统性能状况的结论,并定位瓶颈。
5.1 核心性能指标解读
Analysis提供了数十种图表,但核心关注以下几类:
用户负载相关:
- 运行Vuser图:展示了在整个场景执行期间,处于运行状态的虚拟用户数量变化曲线。它应与你在场景设计中设置的加载策略一致。通过它,你可以确认负载是否按预期施加。
事务相关(最核心):
- 平均事务响应时间图:显示每个事务在整个场景运行期间,平均响应时间的变化趋势。理想情况下,在负载稳定期,响应时间曲线也应该是平稳的。如果曲线随着用户数增加而持续攀升,说明系统存在扩展性问题。
- 事务摘要图:以表格形式给出每个事务的最终统计结果,包括最小、平均、最大响应时间,以及通过/失败的事务数量。重点关注90百分位或95百分位响应时间,它比平均响应时间更能反映大多数用户的体验(避免了极端值的干扰)。例如,“登录”事务的95%响应时间为1.2秒,意味着95%的用户在1.2秒内完成了登录。
系统资源相关:
- Windows资源图或UNIX资源图:这是定位基础设施瓶颈的关键。将“运行Vuser图”与资源图合并查看。
- CPU使用率:持续高于70%-80%可能成为瓶颈。观察是用户态(
%User Time)高还是内核态(%Privileged Time)高。 - 可用内存/内存使用率:如果可用内存持续减少直至接近零,并且磁盘读写频繁,很可能发生了内存泄漏或配置不足,导致大量页面交换(Swap)。
- 磁盘I/O:关注
Disk Read/sec和Disk Write/sec以及Avg. Disk Queue Length。如果队列长度持续大于2,说明磁盘可能成为瓶颈。 - 网络带宽:关注
Bytes Total/sec,与网络适配器的理论带宽对比。
- CPU使用率:持续高于70%-80%可能成为瓶颈。观察是用户态(
- Windows资源图或UNIX资源图:这是定位基础设施瓶颈的关键。将“运行Vuser图”与资源图合并查看。
Web资源相关:
- 每秒点击量图:表示Vuser每秒向服务器发出的HTTP请求数。在负载上升期,点击量应同步上升;在稳定期,应保持相对稳定。如果用户数增加而点击量不增反降,可能意味着服务器已经过载,无法及时处理请求。
- 吞吐量图:表示服务器每秒返回的数据量(字节)。吞吐量的变化趋势通常与点击量类似,但更能反映服务器返回内容的多少。
5.2 合并图表与关联分析
Analysis最强大的功能之一是“合并图表”。通过将两个相关的图表合并,可以直观地发现因果关系。
经典合并案例:
- “运行Vuser” 合并 “平均事务响应时间”:当虚拟用户数增加时,响应时间是否线性增长?如果是,说明应用或数据库可能存在全局锁或资源竞争。如果用户数达到某个拐点后响应时间急剧上升,说明系统达到了并发处理能力的极限。
- “运行Vuser” 合并 “Windows资源 - %Processor Time”:观察CPU使用率是否随着用户数的增加而增加,并在高负载下是否达到饱和(接近100%)。如果CPU先于其他资源饱和,则CPU是瓶颈。
- “吞吐量” 合并 “平均事务响应时间”:在系统性能良好时,吞吐量上升,响应时间平稳或缓慢上升。当系统达到瓶颈时,吞吐量会达到一个峰值并开始下降或持平,而响应时间会急剧上升。这个拐点就是系统的最大处理能力点。
5.3 生成报告与瓶颈定位建议
Analysis可以自动生成多种格式的报告(HTML、Word、PDF)。一份好的性能测试报告应包含:
- 测试概述:测试目标、环境、场景设计简述。
- 关键结果摘要:以表格形式列出核心事务的响应时间(平均、90百分位)、通过率、系统资源峰值使用率等。
- 详细分析与图表:附上关键的合并分析图表,并配以文字说明图表反映的现象。
- 瓶颈分析与建议:这是报告的价值所在。基于数据分析,指出发现的性能瓶颈可能在哪里,并给出初步的优化方向建议。
- 示例:“在并发用户达到500时,‘下单’事务响应时间从2秒陡增至15秒。同时,数据库服务器的CPU使用率达到95%,且磁盘队列长度持续偏高。建议优先检查数据库的SQL语句效率,并考虑增加数据库服务器的CPU资源或优化索引。”
经验之谈:性能瓶颈的定位是一个“提出假设-验证排除”的过程。测试数据给你指明了方向(比如数据库CPU高),但最终确认需要开发、运维同事一起,结合应用日志、数据库慢查询日志、代码Profiling工具进行深度排查。性能测试工程师的价值,在于用数据精准地缩小排查范围。
6. 常见问题与排查技巧实录
即使按照教程操作,在实际使用LoadRunner时也难免遇到各种问题。这里我整理了一份“避坑指南”,涵盖了从脚本到分析全流程的典型问题。
6.1 脚本录制与回放问题
问题1:录制时无法捕获浏览器流量。
- 可能原因与排查:
- 浏览器代理设置问题:VuGen通过系统代理捕获流量。确保录制时VuGen设置的代理端口(默认7777)未被占用,且浏览器正确配置了使用该本地代理。可以尝试用VuGen自带的“代理录制”方式。
- 浏览器兼容性:某些新版Chrome或Edge可能与VuGen的录制组件不兼容。尝试使用VuGen明确支持的浏览器版本(如IE 11),或使用“移动应用/客户端”录制模式中的“代理录制”方式。
- HTTPS证书问题:对于HTTPS网站,需要在VuGen中安装根证书,否则无法解密HTTPS流量。VuGen通常会在第一次录制HTTPS站点时提示安装。
问题2:回放时脚本失败,报404 Not Found或500 Internal Server Error。
- 可能原因与排查:
- 未处理动态Session/Token:这是最常见的原因。检查错误日志,看是否是某个请求参数失效。使用前面讲的“关联”技术解决。
- 硬编码的绝对路径:脚本中可能包含了录制时特定的主机名或IP。使用
web_set_sockets_option或web_add_auto_header函数可能有助于处理,但更根本的是检查所有请求的URL和Host头,确保它们指向正确的测试环境地址。 - 检查点过于严格:检查点寻找的文本在回放时可能因为页面微调而未找到。适当放宽检查条件,或使用更稳定的文本锚点。
6.2 场景执行与监控问题
问题3:大量虚拟用户无法初始化或失败在“Pending”状态。
- 可能原因与排查:
- 负载生成器负载过高或宕机:检查负载生成器的状态是否“Ready”。登录到负载生成器机器,查看任务管理器,CPU和内存是否已耗尽。一台普通的Windows机器,能稳定运行的Vuser数是有限的(Web协议可能几百个),需要分布式部署。
- License限制:LoadRunner的并发Vuser数受License限制。检查License允许的最大Vuser数。
- 脚本初始化部分(
vuser_init)有错误:如果脚本在初始化时就失败(如连接数据库失败),会导致整个Vuser无法启动。单独调试vuser_init部分。
问题4:监控不到Windows/Linux服务器的资源数据。
- 可能原因与排查:
- 防火墙:确保Controller机器和被测服务器之间的
135、445等端口(Windows)或指定端口(Linuxrstatd)是通的。 - 权限不足:Windows监控需要管理员账号密码。Linux监控需要正确的
rstatd服务配置和运行,或SSH密钥认证。 - 计数器名称错误:对于自定义的性能计数器,确保名称完全匹配。最好先在服务器的性能监视器(Windows)或
top/vmstat(Linux)中确认计数器可用。
- 防火墙:确保Controller机器和被测服务器之间的
6.3 结果分析中的困惑
问题5:事务响应时间很长,但服务器CPU、内存都很低。
- 排查思路:
- 网络延迟:检查“网络延迟时间”图。如果网络延迟占据了响应时间的大部分,瓶颈就在网络。可能是测试环境网络带宽不足,或者存在跨地域访问。
- 应用服务器线程池/连接池等待:应用服务器(如Tomcat、WebLogic)的线程池已满,新请求需要排队等待。这不会直接体现在操作系统CPU上。需要监控应用服务器的中间件指标(如活跃线程数、JDBC连接池等待数)。
- 数据库慢查询:请求在等待数据库返回结果。数据库服务器CPU可能不高,但存在锁等待或低效的SQL语句。需要监控数据库的
Active Sessions、Wait Events等。
问题6:测试结果波动很大,每次运行数据差异明显。
- 排查思路:
- 测试环境不干净:被测服务器或数据库上可能运行着其他任务。确保测试环境是独立的、稳定的。
- 未做预热:应用服务器JVM未预热,数据库缓存是冷的。在正式测试开始前,先运行一段时间的低负载场景,让系统进入稳定状态。
- 外部依赖:系统调用了不稳定的外部接口(如第三方支付、短信网关)。在性能测试中,应尽量隔离或Mock掉这些不稳定因素。
- 思考时间与步调时间:如果脚本中设置了随机的思考时间,或者场景中用户加载策略是随机的,那么每次运行的压力模型本身就有差异。对于基准测试,建议使用固定的思考时间和确定的加载模式。
掌握这些排查技巧,能让你在遇到问题时不再慌张,快速定位问题根源。性能测试本身就是一个不断发现、分析和解决问题的过程,这些经验往往比工具操作本身更有价值。