背景介绍
在性能测试工作中,有时需要对业务系统所能支持的最大在线用户数目进行评估。这与我们接触最多的压力测试不一样,因为用户在线时只是与服务器保持连接,并不一定对服务器有业务请求,从而对服务器不一定会产生压力。然而,在线用户数目并非可以无限增长,当在线用户数目达到应用服务器(或者WebLogic等中间件,或者数据库连接池等)的连接数设置的极限时,业务系统同样可能会发生异常,出现新用户无法登录,或者老用户被挤出系统,甚至业务系统宕机的情况。因此,对业务系统的最大在线用户数指标进行测试是极其必要的。
现有一OA系统,需要测试其支持的最大在线用户数目。已知当使用浏览器登录该系统后,登录用户可持续地保持登录状态,即使长时间不做任何操作也不会自动退出系统;通过该OA系统的在线用户数统计模块可以详细地查看到当前在线的用户。
测试方法分析
为了测试被测系统所能支持的最大在线用户数,需要不断地使用新用户帐号进行登录操作,在此同时查看被测系统的在线用户数目以及系统的响应情况。
在新增登录用户时需要注意,由于考察的是系统在正常情况下所能支持的在线用户数目,而不是系统在并发压力下的性能响应情况,因此登录用户时最好采用单个用户或少量并发用户(如两个或三个)逐步登录的形式,不同登录批次之间最好能有一定时间间隔,务必使新增登录用户的操作对服务器产生尽可能小的业务压力。
在新增登录用户的过程中,需要对被测系统的在线用户数目进行查看,并着重关注以下几个方面:
相应地,测试脚本需符合如下形式:
lr_start_transaction("进入登录页面"); /*此处为进入系统登录界面的脚本*/ lr_end_transaction("进入登录页面", LR_AUTO); lr_start_transaction("登录系统"); /*登录脚本--部分1*/
/*对系统登录进行校验 *若成功,即新页面中包含"重新登录",reLogin_Count>0 *若失败,reLogin_Count=0 */ web_reg_find("Text=重新登录", "SaveCount=reLogin_Count", LAST ); /*登录脚本--部分2(包含检查点内容部分)*/ //对系统登录结果进行检查 if (atoi(lr_eval_string("{reLogin_Count}")) == 0) { //登录失败 lr_error_message("登录失败!!!--UserName:%s",lr_eval_string("{UserName}")); //勾选Fail Open Transations on lr_error_message //当执到该lr_error_message时,"登录系统"的Transaction失败 } lr_end_transaction("登录系统", LR_AUTO);
以上脚本调试成功后,通过检查点函数及日志信息可以判断出系统登录操作已通过脚本回放成功完成。
理论上,只要VuGen采用不同帐号迭代运行该脚本,由于只是进行系统登录操作而未进行系统注销或退出操作,业务系统中的在线用户数将持续增加。
然而在该OA系统中采用此方法时发现,虽然脚本成功运行,但业务系统中的在线用户数并未增长。这说明LoadRunner与浏览器在访问系统的过程中存在差异性。
脚本及场景设计
针对上面的问题,通过抓包工具Fiddler2对系统进行网络流量抓包分析可知:用户登录系统后,在未进行任何操作的情况下,浏览器与服务器会定期(间隔30秒)进行通讯交互。如下图所示:

这就解释了为什么用户在浏览器中登录系统后可以长期地保持在线,而通过脚本成功地进行系统登录后却无法保持在线状态;因为VuGen不会像浏览器那样定期地与服务器进行通讯交互。
找出其中的差异后,我们便可在VuGen中用脚本模拟浏览器的定期交互功能,简单的实现方法如下所示。
while(1){ web_url("userAction.struts", "URL=http://10.147.15.28:9001/userAction.struts?actionType=refreshDynaInfo", "Resource=0", "RecContentType=text/html", "Referer=http://10.147.15.28:9001/jsp/oa/infocomm/sms/sysShortMsg/sysShortMsgReflesh.jsp", "Snapshot=t4.inf", "Mode=HTML", LAST); web_url("userAction.struts_2", "URL=http://10.147.15.28:9001/userAction.struts?actionType=refreshDynaInfo&time=Mon%20Aug%2012%2015:42:04%20UTC+0800%202013", "Resource=0", "RecContentType=text/html", "Referer=http://10.147.15.28:9001/jsp/oa/infocomm/sms/sysShortMsg/reflesh.jsp", "Snapshot=t5.inf", "Mode=HTML", LAST); lr_think_time(30); //模拟浏览器与服务器30秒间隔的通讯交互 }
那么,将系统登录脚本和循环函数都放入Action中,在VuGen中采用迭代运行的方式可行吗?
虽然新增登录用户可以逐个进行,即使用VuGen通过Action迭代的形式采用不同帐号逐个地进行登录操作。但由于用户登录后需要持续间隔地与服务器进行通讯交互才能保持在线,而单线程脚本运行至while(1)后便进入死循环,从而使得Action迭代无效。因此,采用VuGen进行Action迭代的方式是不可行的。
正确的做法是,在Controller中采用逐步加载的方式,使各个虚拟用户独立地运行,从而保证了各虚拟用户登录成功后保持在线状态。
在Controller中的具体配置如下所示:
通过以上配置,可以达到如下效果:
测试方法优化
通过以上方法可以测试得到业务系统所能承受的“初略的”最大在线用户数目。为什么说是“初略的”呢?因为该方法仍存在缺陷,主要体现在如下两个方面:
针对以上两方面缺陷,可以做出如下改进:
在本文提到的OA系统中,对链接
http://10.147.15.28:9001/countAction.struts?actionType=listOnlineUser
进行请求可以返回得到当前系统在线用户数目的统计信息。对应地,设计如下脚本,即可实现对系统实时在线用户数目的查看。
Action() { web_add_cookie("USERORGID=db93a2M11f6719ff92Mf528764d624db129b32c21fbca0cb8d6; DOMAIN=10.147.15.28"); while(1){ lr_start_transaction("查看在线用户数目"); web_reg_save_param("OnlineUsers", "LB=[在线用户数/总用户数:", "RB=]", "ORD=2", "Notfound=error", "Search=Body", LAST); web_url("countAction.struts", "URL=http://10.147.15.28:9001/countAction.struts?actionType=listOnlineUser", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTML", LAST); lr_output_message("当前在线用户数目:%s", lr_eval_string("{OnlineUsers}")); lr_end_transaction("查看在线用户数目", LR_AUTO); lr_think_time(3); } return 0; }
更多内容请访问我的个人网站:http://52test.org/posts/Evaluate-Largest-Online-Users.html
转载于:https://www.cnblogs.com/stleo/p/Evaluate-Largest-Online-Users.html
