23
07

使用LoadRunner实现Phpwind的性能测试

在前面的学习中,我们已经利用LoadRunner完成了针对Agileone系统的协议级接口测试。那么本实验主要带大家一起学习一下如何利用LoadRunner完成针对Phpwind论坛的性能测试。

实验简介


在前面的学习中,我们已经利用LoadRunner完成了针对Agileone系统的协议级接口测试。那么本实验主要带大家一起学习一下如何利用LoadRunner完成针对Phpwind论坛的性能测试。

 

实验目的



(1) 掌握LoadRunner中的关联和关联数组用法。

(2) 掌握LoadRunner中的事务和集合点的用法。

(3) 掌握LoadRunner中的场景设计及指标监控。

 

实验流程



1. 为Phpwind实现登录脚本

无论我们使用手工插入web_submit_data的方式生成登录脚本,还是使用录制操作生成脚本均可,本实验的演示代码全部使用手工生成。具体的登录代码如下:


// 登录脚本,其中参数userseq的取值为1到100的随机数
web_submit_data("web_submit_data",
    "Action=http://localhost/phpwind/login.php?",
    "Method=POST",
    "TargetFrame=",
    "Referer=",
    ITEMDATA,
    "Name=forward", "Value=", ENDITEM, 
    "Name=jumpurl", "Value=http://localhost/phpwind/", ENDITEM, 
    "Name=step", "Value=2", ENDITEM, 
    "Name=lgt", "Value=0", ENDITEM, 
    "Name=pwuser", "Value=testuser_{userseq}", ENDITEM, 
    "Name=pwpwd", "Value=123456", ENDITEM, 
    "Name=hideid", "Value=0", ENDITEM, 
    "Name=cktime", "Value=0", ENDITEM,
    LAST);

 

2. 为发帖关联查找验证码


在LoadRunner中的关联查找,与我们在Java中使用正则表达式进行查找其实本质上是一样的,也是通过设置其左右边界进行。在LoadRunner中使用“web_reg_save_param”函数即可实现关联查找,不过也需要将该函数放在被查找的请求的前面,这一点来说与“web_reg_find”是一样的规则。具体的关联设置窗口如下图所示:


20180202_170829_534.png 

 

最终生成的代码为:


// 关联查找发帖的验证码
web_reg_save_param("verifycode",
    "LB=verify\" value=\"",
    "RB=\" />",
    "Ord=1",
    "NotFound=ERROR",
    LAST);

web_url("web_url",
    "URL=http://localhost/phpwind/post.php?fid=2",
    "TargetFrame=",
    "Resource=0",
    "Referer=",
    LAST);

 

3. 实现发帖功能


此处的参数“sequence”为一个10000到99999之间的随机数,具体的代码如下:


web_submit_data("post.php",
    "Action=http://localhost/phpwind/post.php?",
    "Method=POST",
    "EncType=multipart/form-data",
    "TargetFrame=",
    "RecContentType=text/html",
    "Referer=",
    "Mode=HTML",
    ITEMDATA,
    "Name=magicname", "Value=", ENDITEM,
    "Name=magicid", "Value=", ENDITEM,
    "Name=verify", "Value={verifycode}", ENDITEM,
    "Name=atc_title", "Value=这是帖子的标题-{sequence}", ENDITEM,
    "Name=atc_iconid", "Value=0", ENDITEM,
    "Name=atc_content", "Value=这是帖子的内容-{sequence}", ENDITEM,
    "Name=atc_autourl", "Value=1", ENDITEM,
    "Name=atc_usesign", "Value=1", ENDITEM,
    "Name=atc_convert", "Value=1", ENDITEM,
    "Name=digest", "Value=0", ENDITEM,
    "Name=topped", "Value=0", ENDITEM,
    "Name=atc_rvrc", "Value=0", ENDITEM,
    "Name=atc_enhidetype", "Value=rvrc", ENDITEM,
    "Name=atc_money", "Value=0", ENDITEM,
    "Name=atc_credittype", "Value=money", ENDITEM,
    "Name=atc_desc1", "Value=", ENDITEM,
    "Name=attachment_1", "Value=", ENDITEM,
    "Name=att_special1", "Value=0", ENDITEM,
    "Name=att_ctype1", "Value=money", ENDITEM,
    "Name=atc_needrvrc1", "Value=0", ENDITEM,
    "Name=step", "Value=2", ENDITEM,
    "Name=pid", "Value=", ENDITEM,
    "Name=action", "Value=new", ENDITEM,
    "Name=fid", "Value=2", ENDITEM,
    "Name=tid", "Value=", ENDITEM,
    "Name=article", "Value=0", ENDITEM,
    "Name=special", "Value=0", ENDITEM,
    LAST);

 

4. 从首页中查找随机版块


对于函数“web_reg_save_param”来说,除了关联查找到单个的值以外,如果多个值具有相同的左右边界也是可以正常获取到的。我们以查找首页的版块编号以实现随机版块发帖为例,来为大家介绍“关联数组”这一知识点。


(1) 先对Phpwind的首页进行分析,确认可以将所有版块编号关联出来的左右边界。通过实验,我们发现,“thread.php?fid=”和“\" target=\"_blank”可以作为版块编号的左右边界。

(2) 对于web_reg_param函数来说,是查找一个值,还是查找所有值,最大的区别在于“Ord”属性的设置,如果我们要查找到所有的值,则需要设置Ord=All。


web_reg_save_param("forumids",
    "LB=thread.php?fid=",
    "RB=\" target=\"_blank",
    "Ord=All",
    "NotFound=ERROR",
    LAST);

web_url("web_url",
    "URL=http://localhost/phpwind",
    "TargetFrame=",
    "Resource=0",
    "Referer=",
    LAST);

 

// 将从forumids关联数组中随机取得的值保存到参数fid中
lr_save_string(lr_paramarr_random("forumids"),"fid");

 

(3) 一旦我们设置关联函数中的“Ord=All”,即使只找到一个值,也是一个关联数据,其用法有一些改变。比如我们无法直接根据参数名称“forumids”来取得其值,而必须使用类似“forumids_1”或者“forumids_2”等这种方式来取参数值。我们也可以使用“lr_paramarr_random()”函数来从该参数数组中随机取得一个值,所以此时,发帖的代码可以修改为:


web_submit_data("post.php",
    "Action=http://localhost/phpwind/post.php?",
    ITEMDATA,
    "Name=magicname", "Value=", ENDITEM,
    "Name=magicid", "Value=", ENDITEM,
    "Name=verify", "Value={verifycode}", ENDITEM,
    "Name=atc_title", "Value=这是帖子的标题-{sequence}", ENDITEM,
    "Name=atc_iconid", "Value=0", ENDITEM,
    "Name=atc_content", "Value=这是帖子的内容-{sequence}", ENDITEM,
    // 代码略 
    "Name=fid", "Value={fid}", ENDITEM,
    // 代码略
    LAST);

 

由于我们的帖子内容是中文,而Phpwind使用的是UTF-8的编码格式,所以在运行上述脚本的时候也需要确保“Convert to/from UTF-8”被勾选。运行后,我们还可以在“Replay”菜单下的“Test Results”中直接查看运行过程的截图:


20180202_170852_611.png 

 

5. 为登录和发帖添加事务


事务的主要目的是为了在性能测试执行过程中方便统计请求的响应时间,以及结合检查点来统计事务的成功率,及TPS等指标。比如我们可以为登录添加如下的事务:


// 为登录定义检查点,用于判断事务的成功与否
web_reg_find("SaveCount=checkLogin",
    "Text=您已经顺利登录",
    LAST);    

// 定义登录事务的开始,相当于计时器开始工作
lr_start_transaction("doLogin");

// 登录脚本,其中参数userseq的取值为1到100的随机数
web_submit_data("web_submit_data",
    "Action=http://localhost/phpwind/login.php?",
    "Method=POST",
    "TargetFrame=",
    "Referer=",
    ITEMDATA,
    "Name=forward", "Value=", ENDITEM, 
    "Name=jumpurl", "Value=http://localhost/phpwind/", ENDITEM, 
    "Name=step", "Value=2", ENDITEM, 
    "Name=lgt", "Value=0", ENDITEM, 
    "Name=pwuser", "Value=testuser_{userseq}", ENDITEM, 
    "Name=pwpwd", "Value=123456", ENDITEM, 
    "Name=hideid", "Value=0", ENDITEM, 
    "Name=cktime", "Value=0", ENDITEM,
    LAST);

// 根据检查点来决定事务以何种状态结束
if (atoi(lr_eval_string("{checkLogin}"))) {
    lr_end_transaction("doLogin",LR_PASS);
}
else {
    lr_end_transaction("doLogin",LR_FAIL);
}

 

当然,定义发帖的事务和检查点也是类似的方式,此处不再赘述。

 

6. 为请求定义思考时间


在LoadRunner中,思考时间的设置非常简单。只需要在某一个请求后面添加一行代码“lr_think_time(10)”,表示暂停时间为10秒,并在“Runtime Settings”中为思考时间设置随机策略即可,通常建议将思考时间的随机范围设置为50%到150%之间。如果代码中设置的固定思考时间为10秒,则运行过程的思考时间为5秒~15秒之间的一个随机值:


20180202_170918_512.png 

 

7. 为请求定义集合点


如果我们需要为某个请求设置集合点,只需要在该请求前面添加一行代码即可,没有额外设置。比如我们为发帖设置一个集合点,则在POST请求前面添加集合点函数,并设置一个名称即可。


// 为发帖请求设置集合点
lr_rendezvous("gotoPost");
    
web_submit_data("post.php",
    "Action=http://localhost/phpwind/post.php?",
     // 后面的代码略

 

当然,是否使用集合点,是需要我们明确测试需求。我们也可以在Controller中禁用集合点。

 

8. 设置拱型场景


(1) 当我们的脚本开发调试完成后,便可以实现多用户并发操作了。在脚本编辑器的菜单“Tools”中打开“Create Controller Scenario”,并设置并发用户数即可打开Controller。


20180202_170933_565.png 

 

(2) 在场景设计器中,设置Ramp-Up为每20秒钟增加5个用户,Ramp-Down作对应的设置即可完成一个常见的拱型场景的设计,如图所示:


20180202_170943_895.png 


(3) 为本次运行添加Windows性能计数器。切换到“Run”页面中,在“Windows Resources”中添加我们需要监控的关键性能计数器,其过程与我们在Windows自带的性能监视器中的操作一致。

(4) 点击“Start Scenaio”按钮开始运行测试脚本。运行过程中我们还可以实时监控到一些基本的性能指标,如下图所示:


20180202_171020_990.png 

 

9. 分析性能测试结果


当性能测试场景运行结束后,我们可以在Controller的Tools菜单中打开Analysis组件,对相应的性能指标进行分析。LoadRunner的Analysis组件提供了“合并图关联分析”,“自动关联分析”,“多结果对比分析”三个重要功能。此处我们仅就最常用的“合并图关联分析”为大家简单讲解。

合并图的作用是将两种指标合并在一张图上进行分析,可以更加直观地对比指标A对指标B的影响程度。比如我们可以在Running Vusers图表中右键“Merge Graphs”,并选择与“Windows Resources”图进行“Correlate”类型的合并,这样就可以分析“Windows资源利用率情况”中哪些指标受“并发用户数”影响更大。


20180202_171045_515.png 

 

比如通过对下图的分析(X轴代表并发用户数,Y轴代码资源利用率情况),我们可以很清楚地看出,受并发用户数影响最大的指标是“CPU使用率”,其次是“CPU队列长度”和“页交换频率”。当然,受影响越大说明越容易成为瓶颈。比如该图中还有很多指标对并发用户数的增加而几乎是一条直线,无动于衷,则这类指标几乎不可能成为瓶颈。


20180202_171057_039.png 

 

10. 使用负载生成器

在场景设计中,我们还需要考虑一个比较现实的问题,如果我们要模拟10000个虚拟用户怎么办?我们知道,虚拟用户数默认是使用一个线程来模拟一个虚拟用户的,因为线程数只会消耗CPU而不会过多地消耗内存。但是毕竟还是要消耗系统资源,所以一台电脑能够同时并发的线程数量仍然是有限的。经验表明,一台标准的PC机,双核CPU,最多也就能模拟500~1000个线程,CPU使用率就快到达极限了。在这种情况下,我们如果要模拟10000个虚拟用户,意味着需要10~20台电脑才能够完成向服务器发送请求。

最简单的解决方案就是找20台电脑,各自安装LR并运行相同性能测试脚本。但是这样我们面对20台可能没有问题,如果200台电脑,又该怎么办?所以这时候我们需要一套分布式运行系统,LR在这方面为我们考虑得非常周到,提供了“负载生成器”Load Generator这样一种机制,可以通过Controller统一控制负载生成器。那么Controller如何与Load Generator协同工作呢?

打开Controller中的Scenario菜单下的Load Generator,进入负载生成器管理对话框,我们可以将其它需要用于生成负载的电脑一台一台添加进来进行统一管理:


20180202_171115_695.png 

 

要让其它电脑能够提供负载生成服务,那么必须保证这些电脑上安装了LR或者至少安装了Load Generator(在安装LR过程可选择单独安装此组件即可),并且需要启动LoadRunner Agent Service服务(启动后在系统托盘下面显示一个卫星天线的小图标,即表明可以为Controller提供负载生成服务)。

每添加一台负载生成器后点击“Connect”按钮,确保状态从“Down”变为“Ready”表明连接成功,这个时候Controller就可以与负载生成器直接进行通信,将性能测试脚本发送给负载生成器,并由负载生成器向服务器发送请求。当运行结束后,负载生成器再向Controller返回监控到的性能数据,由Controller进行统一管理。

 

那么是不是添加负载生成器后就可以了呢?当然不是,我们还需要为每一个脚本再额外指定由哪些负载生成器来完成。选择菜单“Scenario -> Convert Scenario to the Percentage Mode”,点击确认对话框,而后我们可以看到如下界面,在Load Generators栏下拉,按住Ctrl或Shift键选择需要用到的负载生成器,或者直接选择All Generators,如下图所示:


20180202_171128_667.png 

 

 思考练习


(1) 利用LoadRunner完成对Phpwind的随机回帖的脚本开发

(2) 利用LoadRunner完成文件的上传下载测试。

(3) 利用LoadRunner对当前系统进行性能测试开发与执行,并监控和分析相应数据。






为了答谢大家对蜗牛学院的支持,蜗牛学院将会定期对大家免费发放干货,敬请关注蜗牛学院的官方微信。

20181009_153045_341.jpg




版权所有,转载本站文章请注明出处:蜗牛学苑, https://www.woniuxy.cn/article/75