LoadRunner
C语言开发
模拟高并发负载测试、测试场景搭建、运行、监控及结果分析
支持多协议、自带强大的图表功能、可根据需求合并需要的图表
LoadRunner 11安装
启动安装程序 - setup.exe(提示:权限-鼠标右键->以管理员身份运行);
根据安装提示进行配置并点击下一步操作,直到安装完成;
修改注册许可证
LoadRunner 11破解方法:
a、用LR8.0中的mlr5lprg.dll、lm70.dll覆盖LR11安装目录下“bin”文件夹中的对应文件;
b、运行deletelicense.exe;
c、然后使用老的注册码就可以使用了; global-100: AEAMAUIK-YAFEKEKJJKEEA-BCJGI web-10000: AEABEXFR-YTIEKEKJJMFKEKEKWBRAUNQJU-KBYGB
要使用录制功能,最好安装在win7 使用ie
LoadRunner 12安装
1、管理员启动HP_LoadRunner_12.02_Community_Edition_T7177-15059.exe(不勾选指定LoadRunner代理将要使用的证书)
2、汉化
管理员运行HP_LoadRunner_12.02_Community_Edition_Language_Packs_T7177-15062.exe
运行 软件安装目录下\DVD\Setup.exe,点击语言找到Chinese-Simplified\LoadRunner下的文件
运行D:\loadrunner12\DVD\Language Packs\Chinese-Simplified\LoadRunner\LR_03457.msp安装
3、打开软件验证
要使用录制功能,安装在win7,使用ie即可
安装在windows10 使用旧版firefox
https://ftp.mozilla.org/pub/firefox/releases/ 24.8.1版本
介绍
LoadRunner是一种工业级标准的性能负载测试工具;可以模拟上千万用户实施测试,并在测试时可实时检测应用服务器及服务器硬件的各种数据,来查找和确认存在的性能瓶颈;
支持多种协议,如:Web(HTTP/HTML)、Windows Sockets、FTP、ODBC、MS SQL Server等协议
LoadRunner组成
1. Virtual User Generator(VuGen) 脚本生成器-脚本录制、编辑
2. Controller 控制器-设计场景、运行、监控
3. Analysis 测试结果分析
VuGen
简单操作
loadrunner自带测试服务
LoadRunner\WebTours\StartServer.bat 启动服务
1. 启动网站服务程序
2. 访问地址:http://127.0.0.1:1080/WebTours/
3. 登录账户:用户名:jojo 密码:bean
1. 启动VuGen
直接运行VuGen图标启动或通过LoadRunner管理器启动
2. 创建脚本
3. 选择录制协议 Web(HTTP/HTML)
4. 录制设置
5. 脚本录制
6. 运行脚本( Run 按钮或F5)
7. 查看运行结果
ld11 菜单(View) -> Test Results...
ld12 回放摘要-测试结果
扩展
录制选项-扩展(LD11同LD12)
录制设置Options选项
常规-录制
- HTML-based script: 所有请求放到一个函数内(这里所有请求是指,每步操作所产生的请求)
- URL-based script: 每个请求放到一个函数
1). 基于浏览器的应用程序推荐使用 HTML-based script
2). 不是基于浏览器的应用程序推荐使用 URL-based script
3). 基于浏览器的应用程序中使用了 HTTPS 安全协议,使用 URL-based script 方式录制
HTML Advanced选项
HTML-based script旁边的选项
1. web_submit_form: 依赖上下文才能提交。
2. web_submit_data: 不依赖上下文,每个函数都指定了具体的 URL 地址,可以直接提交成功。【推荐】
没有特殊的场景需求,推荐使用:web_submit_data
运行设置
LD11
菜单-Vuser-Run-time Settings(F4)
LD12
回放-运行时设置(F4)
RunLogic(运行逻辑)
1. 迭代就是脚本要执行的次数
2. Init 与 End 由于只会运行一次,迭代次数设置不会生效
Think Time(思考时间)
改为Replay think time As recorded
1. Ignore think time 默认(忽略思考时间)
2. Replay think time (回放思考时间)
1). As recorded (录制多少秒,就等待多少秒)
2). MuItiply recorded think time by (录制时间的倍数)
3). Use random percentage of recorded think time
( Min(录制时间的最小百分比) Max(录制时间的最大百分比))
4). Limit think time to(限制最高时间)
编译
shfit+F5
常用函数
脚本请求函数(可右键通过工具插入)
web_url()
只能做GET请求
web_url("request name","URL=http://***",LAST);
1). request name:标记请求名称,比如:首页
2). URL=http://xxx:URL=为固定格式;http://xxx为GET请求地址
3). LAST结束标志;
web_url("step1",
"URL=http://192.168.40.1:1080/WebTours/",
"Mode=HTML",
LAST);
web_submit_data()
默认设置是POST请求;也可以做GET请求
web_submit_data(StepName, Action=http://xxx, <List of Attributes>,
ITEMDATA,<List of data>, LAST);
1). StepName:标记请求名称, 比如:登录
2). Action=http://xxx:Action=为固定格式;http://xxx:为提交地址
3). List of Attributes:其他属性 如:"Method=POST"
4). List of data:其他参数 如:"username=jojo"
5). LAST:结束符
web_submit_data("step2",
"Action=http://192.168.40.1:1080/cgi-bin/login.pl",
"Method=POST",
"Mode=HTML",
ITEMDATA,
"Name=username", "Value=jojo", ENDITEM,
"Name=password", "Value=bean", ENDITEM,
LAST);
web_custom_request()
自定义请求方法(GET/POST/PUT/DELETE),用于实现接口测试。
web_custom_request(RequestName, <List of Attributes>,LAST);
1). RequestName:请求名称
2). List of Attributes:属性列表,如:"Method=POST"
3). LAST:结束符
web_custom_request("web_custom_request",
"URL=http://192.168.40.1:1080/cgi-bin/login.pl",
"Method=POST",
"Mode=HTML",
"Body=username=jojo&password=bean",
LAST);
其他函数
lr_output_message() 输出到运行日志
lr_think_time() 思考时间秒 最大可能模仿用户真实操作
strcmp(string1, string2) 字符串比较 返回结果
stricmp(string1, string2) 忽略大小写字符串比较
lr_get_vuser_ip() 可以获取虚拟用户IP地址
ip = lr_get_vuser_ip();
if (ip)
lr_output_message("The IP address is %s", ip);
else
lr_output_message("IP spoofing disabled");
参数化
根据需求动态的获取数据
- 减少重复代码
- 数据代码进行分离,方便维护
设置参数
Parameter name:参数化引用名称(参数化时使用)
Parameter type:File 【推荐】,还有其他的类型比如时间、随机数字
Properties:属性-点击此按钮,可直接设置参数化引用名称对应的值;
LD11
选中要参数化的文本 -> 鼠标右键 -> Replace with a Parameter
或者
菜单 Insert -> New Parameter...
LD12
选中要参数化的文本 -> 鼠标右键 -> Replace with a Parameter
或者
菜单 设计->参数->新建参数
查看设置的参数
LD11
菜单 Vuser -> Parameter List
LD12
菜单 设计->参数->参数列表
参数属性面板设置
Parameter type: 参数类型 File 【重点】
File:参数保存的文件类型及位置,一般为txt;【推荐】
在当前表格编辑数据
Add Column:添加列
Add Row:添加行
Delete Column:删除列
Delete Row:删除行
Edit with Notepad:在记事本内编辑数据;【推荐】
select column 选择使用哪列数据
By number
By name
File format 选择文件每列的分隔符和第一个数据开始的地方
Column
First data
Select next row:运行或迭代时对行的选择方式
Sequential 按照行的顺序读取数据,迭代次数大于行数,从第一行开始读取(单个虚拟用户的时候适用)
Random 随机读取行
Unique 每次读取唯一行,不重复(适合多个虚拟用户)
Same line as xxx 取参数xxx同行, 需要两个以上参数,才能显示和使用
Update value on:运行或迭代时对值的选取方式
Each iteration 每次迭代以后更新,迭代可能用到多次这个参数,参数是一样的
Each occurrence 每次出现参数时更新,迭代可能用到多次这个参数,参数不是一样的
Once 每出现一个虚拟用户(线程)更新一次
When out of values 当超出值时,使用 Unique 选项时会激活
Abort Vuser:中止虚拟用户
Continue in a cyclic manner:以循环的方式继续
Continue with last value:继续使用最后一个值(始终使用最后有一个值)
其中Select next row 与 Update value on为组合关系,不同组合效果不同
- Sequential + Each iteration
- Sequential + Each occurrence
- Sequential + Once
设置参数值
lr_save_string() 设置NULL结尾的字符串作为字符串存入参数
lr_save_int() 设置整数值作为字符串存入参数
lr_save_timestamp("time_stamp", LAST); 设置时间戳作为字符串存入参数time_stamp
lr_save_string("成都", "city");
lr_save_int(1, "count");
lr_save_timestamp("time_stamp", LAST);
lr_output_message("我要去%s", lr_eval_string("{city}_{time_stamp}"));
使用参数
lr_eval_string()
lr_output_message("我要去%s",lr_eval_string("{city}"));
关联
动态获取指定的数据,并把获取的数据通过参数化的方式在另一处引用
查看页面元素响应代码
loadrunner是通过快照功能实现录制和回放得请求和响应分析
通过LR查看
web_url("WebTours",
"URL=http://192.168.40.1:1080/WebTours/",
"Snapshot=t12345.inf",
"Mode=HTML",
LAST);
"Snapshot=t12345.inf" 参数
如果是录制,将会生成这个参数, 如果手动编写脚本,则同样通过设置该参数(t*.inf)然后回放即可查看
查看
LD11
View Tree
菜单-View-Snapshot-View Snapshot
选中录制或者回放 以及 HTTP View
LD12
菜单-查看-快照-录制或者回放(需要选中代码节点)
手动关联(重点)
在web_url函数之前插入关联函数 web_reg_save_param()
设置函数参数
Parameter Name:参数名称(被引用时使用)
Left Boundary(LB):左边界
Right Boundary(RB):右边界
Not Found:关联失败时,处理方式
Search in:匹配搜索响应代码范围
web_reg_save_param("welcome",
"LB=</H1>\n",
"RB=\n"
"<br/>",
"NotFound=ERROR",
"Search=All",
LAST);
单引号(')、双引号(")、反斜杠(\)、回车换行等需要转义字符,加上转义字符[\]
自动关联
LD11 自动关联调用的是关联函数 web_reg_save_param_ex()
LD12 自动关联调用的是关联函数默认是web_reg_save_param_regexp(),可以进行更改
录制时关联
符合关联规则的就自动进行关联,需要启用自动关联设置,依赖于LR自带的规则或新建的自定义规则
LD11
Recording Options-HTTP-Properties-Correlation-勾选Enable correlation during recording
规则在同页面
LD12
录制选项-关联-配置
更改关联的API 录制选项-关联-配置
规则在 录制选项-关联--规则
录制后关联
脚本录制完成并且运行完一次后,打开扫描工具,进扫描需要关联的数据进行关联
LD11
运行一遍脚本:菜单栏(Vuser) -> Scan Script for Correlations
扫描:菜单栏(Vuser) -> Scan Script for Correlations
关联:Correlation Results内进行关联;
LD12
扫描:录制和回放过程中会自动扫描
关联:设计工作室内进行关联,同样可以取消关联
检查点
在回放脚本期间搜索指定的文本或图片,从而验证服务器响应数据的正确性
使用web_find、web_image_check两个函数,必须(启用文本和图片检查)
(在runtime setting -> Internet Protocol-Preferences里面,把Enable image and text check选中,否则不执行该
查找函数)
要使用检查点录制模式必须是HTML-based mode
web_reg_find()
插入函数工具可以实现,可以理解为钩子,需放在请求前使用
Search for specific Text:搜索特定文本
Search in:搜范范围
All :搜索Body+Headers
Body:只搜索Body
Headers:只搜索Headers
Save count:搜索满足条件的数量,并保存在指定的参数名中
Fail if:检查失败的条件
NotFound:没有找到检查失败【推荐】
Found:找到了检查失败
函数包含reg为注册函数,注册函数必须放到依赖执行函数之前(依赖:函数运行后的数据给注册函数使用)
示例:
注意 LD11和LD12可能sample得源代码不太一样
web_reg_save_param("session",
"LB=name=\"userSession\" value=\"",
"RB=\"/>\n",
"NotFound=ERROR",
"Search=All",
LAST);
web_url("WebTours",
"URL=http://192.168.40.1:1080/WebTours/",
"TargetFrame=",
"Resource=0",
"Referer=",
"Snapshot=t27.inf",
"Mode=HTML",
LAST);
web_reg_find("Fail=NotFound",
"Search=Body",
"SaveCount=count",
"Text=jojo",
LAST);
web_submit_data("login.pl",
"Action=http://192.168.40.1:1080/cgi-bin/login.pl",
"Method=POST",
"TargetFrame=body",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/nav.pl?in=home",
"Snapshot=t30.inf",
"Mode=HTML",
ITEMDATA,
"Name=userSession", "Value={session}", ENDITEM,
"Name=username", "Value=jojo", ENDITEM,
"Name=password", "Value=bean", ENDITEM,
"Name=login.x", "Value=0", ENDITEM,
"Name=login.y", "Value=0", ENDITEM,
"Name=JSFormSubmit", "Value=off", ENDITEM,
LAST);
lr_output_message("%s", lr_eval_string("{count}"));
web_find()
插入函数工具可以实现,需放在请求后使用(LD12工具没有该函数,但是可以使用)
web_find("web_find",
"What=jojo",
LAST);
web_image_check()
插入函数工具可以实现,需放在请求后使用
web_image_check("web_image_check",
"Src=/WebTours/images/signoff.gif",
"Alt=SignOff Button",
LAST);
事务
事务(Transaction)是用户在应用软件上操作的一个业务或多种业务集合(Actions)的统称
可统计相应业务的操作时间(事务时间)
可判断相应业务执行的成功与失败
通过事务来衡量服务器性能
添加事务-录制脚本
悬浮框插入开始事务和结束事务
添加事务-手动脚本
Start Transaction
快捷键:Ctrl + T
鼠标右键Insert -> Start Transaction
参数:
Name
End Transaction
快捷键:LD11(Ctrl + D) LD12(Ctrl + SHIFT + T)
鼠标右键Inert -> End Transaction
参数:
Name:
status:
LR_AUTO: 自动-由LR判断
LR_PASS:通过
LR_FAIL: 失败
LR_STOP: 停止
事务响应时间
事务时间 = 响应时间 + 浪费时间 + 思考时间 + 事务代码的执行时间
响应时间
比如网络请求,数据库请求,服务器响应,数据库响应等
思考时间
lr_think_time()函数
浪费时间
LR自动会把一些函数执行的时间统计为浪费时间,比如(关联、检查点)等函数
事务函数执行时间
lr_start_transaction("")和lr_end_transaction("", LR_FAIL)这两句代码执行的时间
集合点
在指定的地点集合指定虚拟用户(Vuser),条件满足时,集合的虚拟用户同时去操作同一事务
添加集合点
鼠标右键 -> Insert -> Rendezvous
集合点设置
基于当前脚本 创建Controller场景
LD11
菜单工具(Tools) -> Create Controller Scenario
LD12
菜单工具(工具) -> 创建Controller场景
选择场景模式及虚拟用户数
场景模式:Manual Scenario(手工场景)
Number of Vusers:虚拟用户数
Controller工具内设置集合策略
Controller工具-菜单(Scenario) -> Rendezvous
创建场景时10个用户,默认10个用户都参与集合点
可指定用户不参与集合点 选择用户-单击Disable VUser按钮
Policy...:设置集合用户策略
当所有虚拟用户中的 x% 到达集合点时释放;
当所有正在运行的虚拟用户中的 x% 到达集合点时释放;
当 x 个虚拟用户到达集合点时释放;【推荐】
Timeout between Vusers:默认30秒;虚拟用户之间的超时时长;
注意:
集合点只能在手工场景模式内使用
多个脚本需要同步并发时,可以在不同脚本内设置相同的集合点,再在一个场景内搭建时使用这些脚本
如果脚本内没有设置集合点,在Controller内集合点策略设置功能不生效!
集合点只能在Action部分添加,在 vuser_init 和 vuser_end 中则无法添加!
Controller
Controller运行方式
VuGen脚本直接启动Controller
直接运行Controller 【推荐】
通过LR工具管理器运行
运行Controller后,提示先选择场景,从VuGen脚本直接启动已经选择好了场景
场景
模拟不同的用户进行不同的操作
Goal-Oriented Scenario(目标场景)
Manual Scenario(手工场景)
Goal-Oriented Scenario(目标场景)
LR会根据根据定义要实现的【测试目标】自动构建场景
虚拟用户数
每秒点击数
每秒事务数
每分钟页面数
事务响应时间
(其中每秒点击数、每分钟页面数只适合Web项目)
创建目标场景
启动Controller
Select Scenario Type:选择Goal-Oriented Scenario
根据测试用例给目标场景添加相应业务(单一业务或混合业务),双击(Available)有效脚本,或选 中点击Add ==>> 按钮
编辑场景
编辑场景目标
Gool Profile Name 选择配置名
Rename 重命名当前计划场景
Delete 删除当前计划场景
New 创建一个新的计划场景
Scenario Start Time:场景启动时间
Without delay:立即运行场景(默认)
With a delay of HH:MM:SS:等待指定时间运行场景
At HH:MM:SS on Y/M/D:指定X年X月X日X时X分X秒运行场景
定义场景目标
实际工作场景中使用最多的还是手工场景,场景的运行和监控都是一样。
Virtual users (虚拟用户)
Hits per Second (每秒点击数)
Transactions per Second (每秒事务数)
Transaction Response time (事务响应时间)
Pages per Minute (每分钟页面数)
Hits per Second 和 Pages per Minute 只适合用于 Web 项目
Virtual users
测试应用程序是否可以同时运行指定数量的虚拟用户数
Hits per Second
目标:测试服务器的每秒点击数
(指定每秒点击数目标以及达到这一目标的最小用户数和最大用户数)
负载行为(Load Behavior)应选择 自动加载(Automatic)
Transactions per Second
目标:测试服务器每秒事务数(指定事务)
(指定每秒完成事务数目标以及达到这一目标的最小用户数和最大用户数)
在VuGen中必须插入相应的事务才能够进行设置!
Transaction Response time
目标:测试在不超过预期事务响应时间(目标)的情况下可以运行多少个用户,
(指定预期时间、最少用户、最大用户)
(如:需求100个人使用支付软件付款,在3秒钟内完成;预期目标时间为3秒,最少用户80,最多用户180)
Pages per Minute
目标:测试服务器每分钟页面数
(指定每分钟完成页面数目标以及达到这一目标的最小用户数和最大用户数)
场景设置
Run time:场景达到目标后,继续运行多长时间;(一般10-30分钟)
If target cannot be reached:如果达不到设定目标时的处理方式
Stop scenario and save results 停止并保存运行结果
Continue Scenario without reaching 继续执行场景直到达到目标位置 【默认】
负载行为
Automatic:系统自动设置【默认】
Reach target number of hits per second 00:10:00 设定10分钟后达到指定的每秒点击数
Step up by 20 hits per second every 00:02:00 表示以每2分钟加载20个点击数
Manual Scenario(手工场景)
在手工场景模式内可以最大程度模拟业务场景(虚拟用户的增加、减少、虚拟用户对混合场景的应用)
创建手工场景
启动Controller工具
Select Scenario Type:Manual Scenario(手工场景)
Use the Percentage Mode to ... 选项:为使用百分比模式,可不勾选
根据测试用例给目标场景添加相应业务(单一业务或混合业务),双击(Available)有效脚本,或选 中点击Add ==>> 按钮
手工场景界面
场景组(默认基础计划)
场景组操作按钮
运行场景
编辑虚拟用户
添加组(脚本)
删除组(脚本)
运行设置-场景内设置 快捷键:F4
查看当前选中组的详情信息(刷新功能)
查看当前选中组脚本-切换回VuGen中
场景组(即写的一个脚本 Vuser组)
Group Name: 组名称(脚本名称)
Script Path:组路径(脚本路径)
Quantity:虚拟用户数量
Load Generators:当前组使用的负载机
场景计划(修改和创建基础计划)
Schedule by 计划方式
Scenario(场景) 场景运行计划同时应用所有勾选的Vuser组
一般选择Scenario,面对混合场景时,计划运行策略只需要设置一次
Group(组) 每个Vuer组(脚本)都要设置单独的运行计划策略
场景中如果存在业务依赖关系时,必须使用Group组(Start Group 设置业务依赖
Run Mode 运行模式
Real-world schedule(实际计划):场景根据模拟用户实际计划操作来运行【推荐】
Basic schedule(基本计划):同实际计划,不同之处是基本计划只能设置虚拟用户在场景一次的启动和停止策略
全局计划(计划运行策略)
场景+真实计划(Scenario + Real-world schedule)
Initialize(虚拟用户初始化策略)
Controller运行Vuser之前对所有Vuser同时进行初始化
Controller在运行指定数目的Vuser之前,根据指定时间间隔对Vuser逐渐进行初始化
Controller在每个Vuser开始运行之前对其进行初始化【推荐默认】
Start Vusers(虚拟用户启动策略)
要启动的虚拟用户数;默认为场景内个Vuser组的Vuser用户总和
同步启动设定的虚拟用户数;
逐渐运行设定的虚拟用户数;默认15秒启动指定虚拟用户,如果小于要启动的虚拟用户数这里不受集合点限制。
Duration(持续运行)
脚本执行一次,如果有迭代,那么执行到迭代次数完成(如果脚本有迭代次数,需要迭代完毕就停止场景的话,选此)
当前场景运行指定时长 (如果选择此项,那么脚本内如果设置有迭代次数,迭代次数设置将失去作用)(如:持续压测5分钟)
Stop Vuser(虚拟用户停止策略)
停止的虚拟用户数,默认All(所有用户),或指定用户数
同步停止设定的用户数
逐渐停止设定的用户数,默认:30秒停止5个虚拟用户
用户组+真实计划(Group + Real-world schedule)
Start Group(多出的,其他同Scenario + Real-world schedule)
Start when group ...... finishes 指定某一用户组(脚本)执行完毕后,执行当前组(脚本)
交互计划图(运行策略直观图)
案例
场景
根据需求分析WebTours订票网站高峰期时25人访问,其中80%用户在使用订票业务,20%用户在使用注册业务;
混合场景 = 注册业务(5) + 订票业务(20)
需求
登录业务时间小于5秒
订票业务小于10秒
提示
注册业务:录制/手工编写注册脚本
订票业务:录制/手工编写订票脚本,脚本内需要插入登录事务和订票事务
用户注册后生成文件 users
案例分析
不需要持续运行
使用5个用户每个用户脚本迭代4次注册20个账户,再使用这20个新注册账户订票;
订票脚本依赖注册脚本
注册脚本参数化:行的选择和更新值方式Unique + Each iteration + Abort Vuser
购票脚本参数化:行的选择和更新值方式Sequential + Once
注册脚本
添加username参数20个用户名
Action()
{
lr_start_transaction("打开首页");
web_url("WebTours",
"URL=http://192.168.40.1:1080/WebTours/",
"TargetFrame=",
"Resource=0",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
LAST);
lr_end_transaction("打开首页", LR_AUTO);
lr_start_transaction("打开注册页面");
web_url("login.pl",
"URL=http://192.168.40.1:1080/cgi-bin/login.pl?username=&password=&getInfo=true",
"TargetFrame=body",
"Resource=0",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/WebTours/home.html",
"Snapshot=t4.inf",
"Mode=HTML",
LAST);
lr_end_transaction("打开注册页面", LR_AUTO);
lr_start_transaction("注册业务");
lr_rendezvous("集合点-注册");
web_submit_data("login.pl_2",
"Action=http://192.168.40.1:1080/cgi-bin/login.pl",
"Method=POST",
"TargetFrame=info",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/login.pl?username=&password=&getInfo=true",
"Snapshot=t5.inf",
"Mode=HTML",
ITEMDATA,
"Name=username", "Value={username}", ENDITEM,
"Name=password", "Value=123456", ENDITEM,
"Name=passwordConfirm", "Value=123456", ENDITEM,
"Name=firstName", "Value=", ENDITEM,
"Name=lastName", "Value=", ENDITEM,
"Name=address1", "Value=", ENDITEM,
"Name=address2", "Value=", ENDITEM,
"Name=register.x", "Value=61", ENDITEM,
"Name=register.y", "Value=9", ENDITEM,
LAST);
lr_end_transaction("注册业务", LR_AUTO);
return 0;
}
订票脚本
添加username参数20个用户名
Action()
{
lr_start_transaction("订票-总");
lr_start_transaction("登录");
web_reg_save_param("session",
"LB=name=\"userSession\" value=\"",
"RB=\"/>\n",
"NotFound=ERROR",
"Search=All",
LAST);
web_url("WebTours",
"URL=http://192.168.40.1:1080/WebTours/",
"TargetFrame=",
"Resource=0",
"Referer=",
"Snapshot=t27.inf",
"Mode=HTML",
LAST);
lr_output_message("%s", lr_eval_string("{session}"));
web_reg_save_param("username",
"LB=Welcome, <b>",
"RB=</b>",
"NotFound=ERROR",
"Search=All",
LAST);
web_submit_data("login.pl",
"Action=http://192.168.40.1:1080/cgi-bin/login.pl",
"Method=POST",
"TargetFrame=body",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/nav.pl?in=home",
"Snapshot=t30.inf",
"Mode=HTML",
ITEMDATA,
"Name=userSession", "Value={session}", ENDITEM,
"Name=username", "Value={username}", ENDITEM,
"Name=password", "Value=123456", ENDITEM,
"Name=login.x", "Value=0", ENDITEM,
"Name=login.y", "Value=0", ENDITEM,
"Name=JSFormSubmit", "Value=off", ENDITEM,
LAST);
web_find("web_find",
"What={username}",
LAST);
lr_end_transaction("登录", LR_AUTO);
lr_start_transaction("打开订票首页");
web_url("Search Flights Button",
"URL=http://192.168.40.1:1080/cgi-bin/welcome.pl?page=search",
"TargetFrame=body",
"Resource=0",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/nav.pl?page=menu&in=home",
"Snapshot=t5.inf",
"Mode=HTML",
LAST);
lr_end_transaction("打开订票首页", LR_AUTO);
lr_start_transaction("订票");
lr_rendezvous("集合点-订票");
web_submit_data("reservations.pl",
"Action=http://192.168.40.1:1080/cgi-bin/reservations.pl",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/reservations.pl?page=welcome",
"Snapshot=t6.inf",
"Mode=HTML",
ITEMDATA,
"Name=advanceDiscount", "Value=0", ENDITEM,
"Name=depart", "Value=Denver", ENDITEM,
"Name=departDate", "Value=09/21/2024", ENDITEM,
"Name=arrive", "Value=Denver", ENDITEM,
"Name=returnDate", "Value=09/22/2024", ENDITEM,
"Name=numPassengers", "Value=1", ENDITEM,
"Name=seatPref", "Value=None", ENDITEM,
"Name=seatType", "Value=Coach", ENDITEM,
"Name=findFlights.x", "Value=37", ENDITEM,
"Name=findFlights.y", "Value=4", ENDITEM,
"Name=.cgifields", "Value=roundtrip", ENDITEM,
"Name=.cgifields", "Value=seatType", ENDITEM,
"Name=.cgifields", "Value=seatPref", ENDITEM,
LAST);
web_submit_data("reservations.pl_2",
"Action=http://192.168.40.1:1080/cgi-bin/reservations.pl",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/reservations.pl",
"Snapshot=t7.inf",
"Mode=HTML",
ITEMDATA,
"Name=outboundFlight", "Value=000;0;09/21/2024", ENDITEM,
"Name=numPassengers", "Value=1", ENDITEM,
"Name=advanceDiscount", "Value=0", ENDITEM,
"Name=seatType", "Value=Coach", ENDITEM,
"Name=seatPref", "Value=None", ENDITEM,
"Name=reserveFlights.x", "Value=40", ENDITEM,
"Name=reserveFlights.y", "Value=9", ENDITEM,
LAST);
web_reg_find("Fail=NotFound",
"Search=Body",
"SaveCount=count",
"Text=Thank you for booking through Web Tours",
LAST);
web_submit_data("reservations.pl_3",
"Action=http://192.168.40.1:1080/cgi-bin/reservations.pl",
"Method=POST",
"TargetFrame=",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/reservations.pl",
"Snapshot=t8.inf",
"Mode=HTML",
ITEMDATA,
"Name=firstName", "Value=Jojo", ENDITEM,
"Name=lastName", "Value=Bean", ENDITEM,
"Name=address1", "Value=", ENDITEM,
"Name=address2", "Value=", ENDITEM,
"Name=pass1", "Value=Jojo Bean", ENDITEM,
"Name=creditCard", "Value=", ENDITEM,
"Name=expDate", "Value=", ENDITEM,
"Name=oldCCOption", "Value=", ENDITEM,
"Name=numPassengers", "Value=1", ENDITEM,
"Name=seatType", "Value=Coach", ENDITEM,
"Name=seatPref", "Value=None", ENDITEM,
"Name=outboundFlight", "Value=000;0;09/21/2024", ENDITEM,
"Name=advanceDiscount", "Value=0", ENDITEM,
"Name=returnFlight", "Value=", ENDITEM,
"Name=JSFormSubmit", "Value=off", ENDITEM,
"Name=buyFlights.x", "Value=47", ENDITEM,
"Name=buyFlights.y", "Value=5", ENDITEM,
"Name=.cgifields", "Value=saveCC", ENDITEM,
LAST);
lr_end_transaction("订票", LR_AUTO);
web_url("SignOff Button",
"URL=http://192.168.40.1:1080/cgi-bin/welcome.pl?signOff=1",
"TargetFrame=body",
"Resource=0",
"RecContentType=text/html",
"Referer=http://192.168.40.1:1080/cgi-bin/nav.pl?page=menu&in=flights",
"Snapshot=t18.inf",
"Mode=HTML",
LAST);
lr_end_transaction("订票-总", LR_AUTO);
return 0;
}
Controller设置
controller打开两个脚本
计划运行策略选择Group + Basic schedule
为每个脚本单独设置策略
注册脚本
场景开始后立即启动
在每个Vuser运行之前将其初始化
启动全部Vuser:延迟5秒启动5个
完成前一直运行
订票脚本
register完成时启动(即所有用户注册完之后启动)
在每个Vuser运行之前将其初始化
启动20个Vuser:延迟10秒启动20个
完成前一直运行
负载生成器
在 LR 中运行场景内脚本的机器被称为负载机
使用负载机
启动Load Generator
菜单栏(Scenario) -> Load Generator
添加负载机
点击添加负载机
输入负载机IP添加本机输入本机 IP或localhost
选择负载机平台(操作系统),支持 UNIX、Windows
测试连接负载机
选中负载机
测试连接负载机
查看测试结果(Ready:通过;Down:未连接;Failed:失败)
场景-用户组(脚本)选择相应的负载机
负载机配置
Windows
Windows直接通过LR安装包安装LR或者Load Generator(可以只安装这个)
负载机与控制机网路通畅
代理服务程序
负载机必须启动 LoadRunner Agent Process 代理服务程序;
(位置:开始程序 -> HP LoadRunenr -> Advanced Settings -> LoadRunner Agent Process)
负载机上的防火墙为关闭状态
权限配置
负载机运行设置工具内输入负载机本机登录用户名和密码,目的解决是控制机远程连接负载机的权限问题
(管理员运行 位置:开始程序 -> HP LoadRunner -> Tools -> LoadRunner Agent Runtime Settings Configuration)
够解决LR控制机连接负载机的权限问题
如果选择 Allow virtual ...后 LoadRunner Agent Process 服务消失
也可以选择使用 Manual log ...手动登录的方式实现授权!
Linux
Linux需要从官网或其他网站下载loadrunner-1x-load-generator.iso场景运行
镜像方式
配置源
cd /etc/yum.repos.d/
mkdir back
mv * ./back/
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum install compat-libstdc++-33
yum -y install gcc gcc-c++ libstdc++.so.5
yum -y install csh
mkdir -p /opt/loadrunner/iso/
mount -o loop loadrunner-11-load-generator.iso /opt/loadrunner/iso/
/opt/loadrunner/iso/Linux/installer.sh
增加LR负载端用户: useradd -g 0 -s /bin/csh loadrunner
修改LR配置
vi /etc/csh.cshrc 在最后一行加上: source /opt/HP/HP_LoadGenerator/env.csh
vi /opt/HP/HP_LoadGenerator/env.csh 在最后一行加上: setenv DISPLAY 0.0
验证
su - loadrunner
env
cd /opt/HP/HP_LoadGenerator/bin/
./verify_generator
启动LR负载机
/opt/HP/HP_LoadGenerator/bin/m_daemon_setup start
查看日志
tail -f /tmp/m_agent_daemonzFa8XO.log
场景运行
场景设计页面下,点击 Run切换到场景运行界面
场景运行界面
场景运行界面
场景用户组虚拟用户运行状态图(左上)
Down(关闭):Vuser处于关闭状态
Pending(挂起):Vuser已创建,可以初始化,正将脚本传输到负载机
Init(初始化):Vuser正在负载机上执行初始化
Ready(就绪):Vuser已执行脚本初始化部分(init函数),可以运行Action函数
Run(正在运行):Vuser脚本正在运行
Rendezvous(集合点):Vuser到达集合点,等待条件满足释放
Passed(完成并通过):Vuser已运行结束,状态为通过
Failed(完成并失败):Vuser已运行结束,状态为失败
Error(错误):Vuser运行中发生了错误
Gradual Exiting(逐步退出):Vuser正在运行退出前的最后一次迭代
Exiting(退出):Vuser已经完成操作,正在退出
Stopped(停止):Vuser被停止,不在运行
场景运行状态概览图(右上)
操作区
Start Scenario 开始场景
Stop 停止场景
Reset 清除上次场景运行记录
Vuers... 对场景当前选中脚本的虚拟用户进行修改(运行、添加、删除、指定负载机)
Run/Stop Vusers... 对当前场景内虚拟用户进行操作(运行、停止)
结果区
Running Vusers 运行用户数
Elapsed Time 已运行时间
Hits/Second 每秒点击数
Passed Transactions 通过事务数
Failed Transactions 失败事务数
Errors 错误数
可用性能计数器及性能计数器指标走向图(下)
可用图指标(左上)
显示可用图指标指定的图表(右上)
对应用服务器硬件资源(CPU、内存、网络、磁盘)等性能指标进行度量统计(下)
运行
点击 Start Scenario 开始场景运行
Analyze Result(分析报告)
详细报告数据可以通过Analyze Result得到
场景运行之后通过菜单栏(Results->Analyze Result)
性能资源指标监控与服务水平协议(SLA)
性能资源指标监控
LoadRunner中添加资源性能计数器
windows
目前只成功了本机
在 Available Graphs(可用图) 激活 System Resource Graphs(系统资源图)下的windows资源
在系统资源图表上鼠标右键 -> Add Measurements(添加度量值)
添加监控的服务器计算机(localhost)或者远程ip
添加远程windows注意事项
确保LR控制机与需要监控的PC机网络通畅
Remote Procedure Call (RPC)、Remote Procedure Call (RPC) Locator、Remote Registry、 Workstation 这些服务都需要确认为已启动状态。
本地账户共享和安全模型-经典-对本地用户进行身份验证不改变其本来身份【win7旗舰版默认】(gpedit.msc 计算机配置->Windowns设置->安全设置->本地策略->安全选项->网络访问:本地账户共享和安全模型)
添加指标观测
% Disk Time
Available MBytes
% Processor Time
linux
主要是需要服务器运行rstatd
yum -y install rsh*
yum -y install rusers-server
systemctl start rstatd
rpcinfo -p
在 Available Graphs(可用图) 激活 System Resource Graphs(系统资源图)下的Unixs资源
在系统资源图表上鼠标右键 -> Add Measurements(添加度量值)
添加监控的服务器计算机远程ip
linux需要安装运行rstatd
添加指标观测
User mode CPU Utilization
Disk Traffic
。。。
服务水平协议(SLA)
Service Level Agreement(SLA) 是在场景执行之前定义相应的负载测试目标,在场景运行之后 Analysis 将运行时收集的指标值和SLA设定的进行对比,然后确定本次测试是成功还是失败。
在场景设计区域,右上侧有个SLA专栏。
测试需要有预期结果,SLA就是给场景运行之前给相应指标设定个预期结果。
SLA使用和查看
需求
订票网站,20用户同时订票,登录在3s内完成,订票在15秒内完成;
新建SLA
为目标选择度量
选择事务响应时间(Percentile(百分比)、Averge平均值)
每秒错误数
总点击数
每秒平均点击数
总吞吐量
平均吞吐量
选择事务
设置事务预期值
设置90%登录用户时间小于等于3秒
设置90%订票业务小于等于15秒
完成SLA服务创建
运行之后
analysis中事务摘要查看事务SLA的状态
analysis中服务水平协议报告查看事务SLA的状态
IP Wizard(IP 欺骗)
配置:使用 IP Wizard 工具配置 IP(管理员权限)
应用:运行场景时启用 Enabled IP Spoofer
IP Wizard工具
开始菜单 -> HP LoadRunner -> Tools -> IP Wizard
启动IP Wizard工具时,电脑 IP 地址必须为【静态IP地址】,不可用 DHCP 动态获取
创建IP
输入 IP 地址段
点击Add,添加IP对话框
选择IP类型,默认C类
添加IP起始段和Submask地址
批量添加IP的数量
勾选验证新ip未被使用
Controller使用
勾选 Enabled IP Spoofer(启用IP欺骗) Scenario -> Enable IP Spoofer 场景-ip欺骗器
虚拟用户模式选择进程模式(默认为线程) F4-其他
启用专家模式 -> 菜单Tools -> Expert mode
设置多个 IP 模式为进程 菜单Tools -> options -> General -> Multiple Ip address mode(IP address allocation per process)
LoadRunner 安装目录下 dat 文件夹下 mdrv.dat 文件内 lr_socks 选项添加ExtCmdLineConc=-UsingWinInet Yes
忽略Web页面诊断 菜单Diagnostics -> Diagnostrics Distribution -> Web Page Diagnostics...)
删除IP(测试完毕时使用)
选择 Restore original set(恢复原始设置)
输入服务器IP地址
完成即可
使用IP Wizard 注意事项
运行场景时,启用 Enabled IP Spoofer 选项
虚拟用户模式选择进程模式(默认为线程)
负载机需要设置 IP Wizard
案例
20个用户使用订票业务(不同的 IP)
录制订票业务脚本
搭建订票场景 用户数20
使用IP Wizard工具生成20个IP地址
启用IP欺骗(Enable IP Spoofer)
运行场景-查看虚拟用户日志(可以看到使用的ip)用户日志可以通过F4运行时更改为不是在只错误的时候记录
查看Analysis Result报告
Analysis
摘要报告
分析概要
场景名
会话中的结果数
持续时间
统计信息概要表
运行 Vuser 的最大数目
总吞吐量(字节)
平均吞吐量(字节/秒)
总点击次数
平均每秒点击次数
5 个最差事务
事务名
目标
实际
冲突(%)
事务摘要
事务名称
SLA 状态
最小值
平均值
最大值
标准偏差
90 百分比
通过
失败
停止
HTTP 响应概要
HTTP 响应
合计
每秒
查看与添加图表
图目录下的即是各种图表
添加图表 快捷键: Ctrl + A 可弹出添加图表对话框
Vusers 有关虚拟用户图表,如集合点图
Errors 有关错误图表
Transactions 有关事务图表
Web Resources 有关Web页面图表
Web Page Diagnostics 有关Web页面组件图表
System Resources 有关服务器资源图表
拐点分析法
性能瓶颈主要产生原因就是某个资源的使用达到了极限,此时表现为随着压力的增大,系统性能却出现极具下降,这时产生了拐点现象
思路:只要得到拐点附近的资源使用情况,就能定位出系统性能瓶颈所在
合并图
案例
使用订票脚本,设计个场景,场景需求设置:
设置:
1). 虚拟用户数20;
2). 场景模式 + 基本计划
3). 虚拟用户启动15秒启动2个,结束与启动相同;
4). 持续时间为2分钟。
合并图表是为了更好的定位系统瓶颈,比如把虚拟用户运行图和平均响应事务时间合并,能直观体现虚拟用户数量对服务器处理事务产生的影响
合并
Running Vusers(虚拟运行用户)
Average Transaction Response Time(平均事务响应时间)
打开合并选项菜单 (Ctrl + M 或者 在要合并的图表上点击鼠标右键 -> Merge Graphs 合并图)
选择要合并的图(并入) 如:Running Vusers
选择合并的方式:
Overlay(叠加)
两个图使用相同的X轴,并入的图Y轴合并后在最右侧
Tile(平铺)
两个图公用一个X轴,Y轴各自保持不变,并入图在上方
Correlate(关联)
主图的Y轴变成合并后的X轴,合并图的Y轴,为合并后的Y轴;
合并的时候,需要把多余的线条给过滤掉,如:只留订票业务;
以上图为例,合并后X轴为平均响应时间,Y轴为虚拟用户数
自动关联
打开合并选项菜单 (Ctrl + R 或者 在要合并的图表上点击鼠标右键 -> 自动关联)
LoadRunner使用统计信息算法去关联相似事务波段的指标,从而来定位某一瓶颈是由那些指标引起的
选择指定关注的时间段
选择关联选项
常用合并图表组
平均事务响应时间与虚拟运行用户
直观体现 虚拟用户数对不同事务的影响
平均事务响应时间与吞吐量
单个事务对吞吐量的影响
每秒点击数与吞吐量
正常情况下每秒点击率与吞吐量图形基本是一致的
每秒点击数与平均事务响应时间
查看每秒点击数对事务的影响
交叉结果与性能报告生成
交叉结果
交叉结果是指相同场景下两次测试结果进行交叉对比,在 LR 中把这种对比两次结果指标叫做交叉结果
Controller-结果-结果设置-自动为每次场景执行创建结果目录
在Analysis result上
菜单 文件 -> Cross with Result...(交叉结果)
Add添加上次结果目录文件
两张报表有的数据都会产生对比
性能报告生成
在Analysis result上
生成模板
Analysis菜单(Reports) -> New Report,直接点击 Generate(生成)模板
在模板上导出指定报告类型
在报告模板内选择保存 -> Microsoft Word 2007 File或其他格式
导出设置,默认ALL(全部)导出 直接点击OK
保存报告路径和名称
主要图表分析说明
- 虚拟用户相关图表
- 错误相关图表
- 事务相关图表
- Web资源相关图表
- 网页诊断相关图表【Web项目关注 重点】
- 系统资源相关图表
Linux资源监控方式
命令 方式
top (系统资源管理器)
vmstat (查看虚拟内存状态)
free(查看未使用的和已使用的内存数目)
iostat (查看io磁盘信息)
sar 网络
top
1). 第一行 任务列队基本信息
- 06:49:14 :系统当前时间
- up 2:32 :系统运行时间 2小时32分钟
- 3 users:当前登录用户数
- load average:系统负载,即任务队列的平均长度-(1分钟、5分钟、15分钟)到现在的平均长度
2). 第二行 进程列队信息
- Tasks : 201 total 进程总数
- 2 running 正在运行进程数
- 199 sleeping 睡眠进程数
- 0 stopped 停止运行的进程数
- 0 zombie 僵尸进程数
3). 第三行 CPU信息
- 0.3 %us:用户空间占用CPU百分比
- 0.3 %sy: 内核空间占用CPU百分比
- 99.2%id: 空闲CPU百分比
4). 第四行 内存信息
- Mem : 3908524 ktotal 物理内存总量
- 1294032 used 使用的物理内存总量
- 2614492 free 空闲内存总量
- 74352 buffers 用作内核缓存的内存量
5). 第五行 交换区内存
- Swap : 4046844 total 交换分区总量
- 0 used 使用的交换区总量
- 4046844 free 空闲交换区总量
- 297720 cached 缓冲的交换区总量
- 1936060 avail Mem 真实可用的内存 有的操作系统才会有
vmstat
查看内存明细
Procs(进程)
r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。
Memory(内存)
swpd: 使用虚拟内存大小,如果swpd的值不为0,但是SI,SO的值长期为0,这种情况不会影响系统性能。
free: 空闲物理内存大小。
buff
cache
Swap
si: 每秒从交换区写到内存的大小,由磁盘调入内存。
so: 每秒写入交换区的内存大小,由内存调入磁盘。
IO
bi: 每秒读取的块数
bo: 每秒写入的块数
system
in: 每秒中断数,包括时钟中断。
cs: 每秒上下文切换数。
上面2个值越大,会看到由内核消耗的CPU时间会越大。
CPU
us:用户进程执行时间百分比(user time)
sy:内核系统进程执行时间百分比(system time)
id: 空闲时间百分比
wa: IO等待时间百分比
free
free -m (-m:以MB为单位显示内存使用情况)
total:内存总数;
used:已经使用的内存数;
free:空闲的内存数;
shared:当前已经废弃不用;
buffers Buffer:缓冲内存数;
cached Page:缓存内存数。
(-buffers/cache) used内存数:第一部分Mem行中的 used – buffers – cached=程序占用内存数
(+buffers/cache) free内存数: 第一部分Mem行中的 free + buffers + cached=可挪用内存数
iostat
iostat是查看Linux系统io
iostat -x 1 1
(x:输出列,1:间隔1秒,1:采集1次)
CPU
%user: 在用户级别运S行所使用的CPU的百分比
%system: 在系统级别(kernel)运行所使用CPU的百分比
%iowait: CPU等待硬件I/O时,所占用CPU百分比
%idle: CPU空闲时间的百分比
Device
tps: 每秒钟发送到的I/O请求数 不加-x参数会有
avgqu-sz: 是平均请求队列的长度,毫无疑问,队列长度越短越好
await:每一个IO请求的处理的平均时间(单位是毫秒)
rkB/s: 每秒读取数据量(单位kb)
wkB/s: 每秒写入数据量(单位kb)
%util: 磁盘的繁忙程度,如接近100%那说明磁盘已经到瓶颈
sar
sar命令可以通过参数单独查看系统某个局部的使用情况
sar -n DEV 1 2
查看网卡的情况
rxkB/s: 每秒接收的数据大小,单位kb
txkB/s: 每秒发送的数据大小,单位kb
sar -u 1 2
查看CPU资源的情况
%iowait: 显示用于等待I/O操作占用 CPU 总时间的百分比
若 %iowait 的值过高,表示硬盘存在I/O瓶颈
%idle: 显示 CPU 空闲时间占用 CPU 总时间的百分比
sar -r 1 2
查看内存和交换空间情况
kbmemfreee: free命令中的free值
kbmemused: free命令中的used值
%memused: kbmemused和内存总量(不包括swap)的一个百分比
kbbuffers: free命令中的buffer值
kbcached: free命令中的cache值
sar -d 1 2 -p
查看设备使用情况
await: 从请求磁盘操作到系统完成处理,每次请求的平均消耗时间,包括请求队列等待时间,单位是毫秒(1秒=1000毫秒).
sar -q 1 2
查看进程队列长度和平均负载状态
runq-sz 运行队列的长度(等待运行的进程数)
plist-sz 进程列表中进程(processes)和线程(threads)的数量
ldavg-1 最后1分钟的系统平均负载(System load average)
ldavg-5 过去5分钟的系统平均负载
ldavg-15 过去15分钟的系统平均负载
怀疑CPU存在瓶颈,可用 sar -u 和 sar -q 等来查看
怀疑内存存在瓶颈,可用sar -r 等来查看
怀疑I/O存在瓶颈,可用 sar -u 和 sar -d 等来查看
工具 nmon和nmon_analyser
nmon and njmon | Site / Download (sourceforge.io)
mkdir result
./nmon_x86_64_centos7 -s3 -c10 -f -m result
-s:时长-采集数据频率 秒
-c:采集次数
-f:生成文件名包含文件创建时间
-m:指定生成文件保存目录
nmon文件在result目录下
使用nmon_analyser文件分析nmon文件生成xlsx文件包括了图表等信息