LR总结笔记(二)

负载测试、压力测试、配置测试、并发测试、可靠性测试、基准测试
P3 P4
系统资源监控
windows:
1.使用loadrunner直接监控,但是C盘必须能访问,在LR的Monitors下面有Add Measurements可以添加度量
2.使用性能工具:在计算机管理内---性能---监视工具---性能监视器,可以查看当时性能。
Windows性能日志

  Windows Server 2008引入了数据收集器集和报告。利用数据收集器集可以指定希望跟踪的性能对象和计数器集。

  可以使用单一数据集生成多个性能计数器和跟踪日志,还可以:

(1)指定访问控制,以管理谁可以访问所收集的数据。

(2)为监视创建多个执行计划和停止条件。

(3)使用数据管理器控制所收集数据和报告的大小。

(4)根据所收集的数据生成报告。 
性能---数据收集器集---用户定义---右键新建数据收集器集---选择手动创建---选择创建数据日志勾选性能计数器---添加计数器---设置时间间隔单位为秒或其他---保存位置:%systemdrive%\PerfLogs\Admin\Sql性能监视器---选择保存并关闭---找到刚创建的集,内有一个数据收集器,右键属性---从“日志格式”列表中选择“逗号分隔”---找到刚刚创建的集,右键属性---在计划选项卡上,添加监视计划,然后结束设置。
内存三个指标:Available Bytes(可用,不小), Memory pages(硬页错误从磁盘读取或写入速度,不高),Page Faults(出错页面的平均数,不高)
内存泄露:1.进程分配内存后,但未将用完的内存回收,该进程越来越大。2.观测内存分配池Pool Paged Bytes,内存分配池中可用内存消耗不断上升。

磁盘四个指标:%Disk Time(忙于读写请求服务的时间百分比,<10),Averge Disk Queue Length(平均队列,<0.5),Averge Disk Seconds/Read/Write(平均读写,无,但分寻道、旋转延迟、数据传输)

CPU三个指标:%ProcessorTime(使用率<85,user进程 system进程),%UserTime(user进程),%PrivilegedTime(system进程)

linux
1.命令监控
CPU三个指标:运行态、就绪态、等待态(阻塞态)1.CPU队列 2.CPU繁忙程度 3. CPU高密集程序

CPU队列、CPU繁忙程度命令:vmstat 2 10 隔2秒 采集10次
r 可运行的内核线程平均数据,不能大于CPU的数目
b VMM虚拟内存等待队列中的内核线程平均数 <核数*0.7 2盒小于1.4
cs 每秒上下文切换次数
us和sy和id 是cpu的用户和系统进程和空闲比( <15)

CPU高密集程序命令:ps -au 进程 au由高到低排列 ef由低到高排序

内存SWAP(使用虚拟内存的块)Buffers(temp文件读取)
命令:vmstat 2 10 隔2秒 采集10次
buffer越少越好,cache越多越好。si input,so output比例应该为0,如果非0就是要靠SWAP调虚拟内存

查看统计信息命令:vmstat -s

查看更细致信息命令:ps -v
RSS进程大小

磁盘三个指标:物理转对应多个逻辑转,逻辑转对应多个文件系统,文件系统对应挂载点,
命令:iostat 5 2 隔5秒 采集2次
sda是逻辑转

命令:如果没有安装sysstat包 rpm -ivh systat-7.0.2-3.el5.i386 包括iostat、mpstat、sar和sa工具
sar -d 3 3
Avwait就是队列长度

测试磁盘当时空负载和负载的读写当时情况,命令:
写入:time dd if=/dev/zero of=/test.dbf bs=8k count=30000
读取:tiem dd if=/dev/sda1 of=/dev/null bs=8k count=30000
读写:tiem dd if=/dev/sda1 of=/test1.dbf bs=8k count=30000

网络使用工具监控

2.nmon监控可以记录并且写报告
安装nmon后 更改权限为chmod 777 文件夹


Web 服务监控
Apache 需要打开LoadHodule status_module modules/mod_status.so才能打开监控模式

在地址栏输入http://localhost/server-status
Total accesses:总请求数
Srv PID Acc M SS Req Conn Child Slot Client VHost Request
PID 进程
Req 请求数
Conn 连接数
Child 孩子间接
Request 请求方式
M的方式可以查看下面注释
带参数输入url:?auto是否动态刷新,refresh刷新秒
如:http://localhost/server-status?auto&refresh=5
Total Accesses:总连接量
Total kBytes:接受总字
Uptime:运行总时间
ReqPerSec:平均每秒请求数
BytesPerSec:平均每秒发送的字节数
BytesPerReq:平均每个请求发送的字节
BusyWorkers:正在工作数(线程)
IdleWorkers:空闲数(线程)

运行时配置:
1.AllowOverride是否允许覆盖,一般是None
2.HostnameLookups 主机对DNS的查找,一般是off
3.FollowSymLinks 是否重复检查连接符的安全性,可以设置
<Directory>
    Options FollowSymLinks
</Directory>
<Directory/www/htdocs>
    Options-FollowSymLinks+SymLinksIfOwnerMatch
</Directory>
4.内容协商Content Negotiation

多路模块处理
windows:mpm_winnt
linux:preforkMPM\workerMPM
ThreadsPerChild 每个孩子的进程数 最大是1920,建议100-500之间
MaxRequestsPerChild 默认为0,建议是1以上数值。
MaxSpareServers 自动为MaxSpareServers+1,建议比MinSpareServers,如果系统繁忙会启动这个参数,多余的会被杀掉。
ServerLimit要比MaxClient大

测试的时候去掉ExtendedStatus On和LoadHodule status_module modules/mod_status.so两个模块加#

但是tomcat没有涉及到!

数据库监控:
数据库内外压力内存瓶颈:
CPU瓶颈:
磁盘瓶颈:
等待类型:1.丢失更新 两个数据同时对一条数据更新,结果更新的数据并不是两个数据的总和
2.脏读 一个数据,其中一个人数据还原到原始数据,被另外一个人已经使用新数据。
3.不可重复读 因为数据一直在更新,所以被读取永远不是最新的。
4.幻影 一个插入或删除数据,在另外一个关联的表内没有做相同的插入或删除数据,造成其中一个多出数据。

数据库的监控使用软件
可以捕捉阻塞时间,

登录jojo项目
分开做步骤在analysis有时间统计
open_index 打开页面
submit_login 提交参数
into_flight 点击进入业务页面
find_flight 选择完成后点击
select_flight 选择完成后点击
pay_flight 选择完成后点击,检查金额
sign_off 选择退出

账户操作参数化 username usersession
出发及到达城市随机
随机某个航班

创建参数t001、t002

开始录制,完成后检查,开始做usersession的关联。
<input type=hidden name=userSession value=125074.11964358ztDDfAApAcQVzzzHDizAVpAAAVHf>
web_reg_save_param("userSession1","LB=userSession\" value=\"","RB=\">",LAST);
增加判断:
web_reg_find("Text=welcome","SaveCount=loginflag",LAST);
进入页面显示welcome
if(atoi(lr_eval_string("{loginflag}"))>0)
{
  lr_output_message("loginOK");
  return 0;}
else
{
  lr_output_message("loginFAIL");
  return -1;}
设置断点调试
打开扩展日志
并且错误的脚本,编译后试一下。
查看结果:replay---Test Result。

web_reg_save_param("flights","LB=\">","RB=</option>","ORD=ALL",LAST);

两种随机循环:
自带随机函数lr_paramarr_random("flights");代码如下:

char *departcity,departcitys[30];
char *arrivacity,arrivacitys[30];
departcity = lr_paramarr_random("flights");
arrivacity = lr_paramarr_random("flights");
//增加一次选择,防止重复
while(1){
  if(arrivacity == departcity)
    arrivacity = lr_paramarr_random("flights");
  else
    break;
}
lr("%s",departcity);
lr("%s",arrivacity);
sprintf(departcitys,"Value=%s",departcity);把Value=departcity变为departcitys变量
sprintf(arrivacitys,"Value=%s",arrivacity);
lr("%s",departcitys);
lr("%s",arrivecitys);

可以直接更换"Value="替换为departcitys,arrivecitys。


设置{departdate}进入Parameter List中选择Parameter type为Date并可以更改%a/%d/%y为%Y,就是年的全称2018。

在随机前
web_reg_save_param("fightline","LB=outboundFight\" value=\"","RB={departdate}","ORD=ALL",LAST);
在随机处
char *flightno;
char flightnumber[25];
flightno = lr_paramarr_random("flightline");
如果判断参数的关联:sprintf(flightnumber,"Value=%s%s",flightno,lr_eval_string("{departdate}"));
lr("%s",flightnumber);

可以直接更换"Value=151;285;{departdate}"替换为flightnumber。
如果是全局变量需要提char flightnumber[25];到外面,从这个action以下都可以使用这个变量。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
另外一种取随机数:
char departstr[20];
int flightcount;
int departrandnum=0;
flightcount=atoi(lr_eval_string("{flights_count}"));
lr("%s",flightcount);
departrandnum = rand()%(flightcount/2)+1;
sprintf(departstr,"{flights_%d}",departrandnum);
lr(lr_eval_string(departstr));

========================================================
PP15 10:00
发送邮件LR
HTML协议
open_index//打开页面
submit_login//提交登录
send_message//进入后等待完成,点击写信,输入地址主题内容并发送
sign_off//点击退出
http://mail2.163.com

如果LR给的不符,因为是BS架构,可以查看页面,
sid=SBGlsUOOhhykEUwQiROOzRPwcwiXGFUt&df=mail163_letter#module=welcome.WelcomeModule%7C%7B%7D

sid=mCsGxnppKBwunzVajLppbUQXxYicYNxz&df=mail163_letter#module=welcome.WelcomeModule%7C%7B%7D

放在获取地址之前:
web_reg_save_param("usersession","LB=suid:'',sid:'","RB=',cosid:",LAST);
查看回放日志:发现<string name="info">Func:N/A,Code:FA_INVALID_SESSION</string>
使用Replace替换所有的asldfkjaslkfdjsf为{usersession}

==================================================
场景举例:
单交易基准测试
登录支持10分钟300个用户登录,并发送不少于20,相应时间不超过3秒,业务成功100,CPU内存不超过80%。
分成两个业务测试类型:业务量测试,并发测试
业务量测试:10分钟300个用户,需测试出单词登录消耗时间,计算vuser的数量。
通过lr统计,单次登录消耗6秒,10分钟内可以模拟出100个用户登录,所以需要3个vuser数量。
如果希望模拟真实用户,用户名需要参数化,类型file(unique %3d,start=1)类型,300*1.2=360个参数。
如果使用lr构造,可以在run-time settings内run logic内选择insert block,插入一个块,然后把要重复操作的插入到块内,同时更改parameter list内的update value为each iteration换成each occurrence。因为要每次触发换参数,而不是从头到尾的迭代一次换参数。
==========================================
进入controller
进入controller后查看代码,选择脚本再选择view script,进行更改,但是更改后不会自动更新,需要点击detail内的refresh---script。
在场景内设计一段时间后,迭代就不起作用。
在run-time setting设置:
在场景内需要启动发生错误需要继续。在勾选deline each action as a transaction。另外如果想模拟浏览器的用户行为:选择browser下的browser emulation---勾选simulate browser cache---勾选cache URLs requiring content---勾选Check for newer versions of stroed page every vi。
还需要设置集合点,来让压力集中释放。
最后需要设置results---set results的位置。

进入run
可以设置显示16张图表,在windows 监控内需要添加measurenation计数器,进入后先设置ip,如果是本地就是localhost,然后把下面的都删了,然后再监控什么添加什么,等待5秒后才会有显示。
开始跑,然后点击analysis。


====================================================
一个性能测试的例子,脚本的开发
接口:协议HTTP POST GET
名词解释:
URL:
参数:
错误相应输出:
错误码定义:
例子:

vuser_init(){
  lr_load_dll("md5.dll");
  return 0;
}

  char secret_key[32] = "oweolsdoiowiwql";
  char api_key[32] = "zhangdanzhongxin";
  char method[32] = "datacenter.getBillGas";//开发的一个接口
  char timeOfSecond[12];
action(){
  char bd_sig[100];
  typedef long time_t;
  time_t t;
  springf(timeOfSecond,"%ld", time(&t));//拿到时间
  lr_save_string(timeOfSecond, "call_id");//字符串转参数
  lr_output_message("%s", timeOfSecond);//打印时间
  //bd_sig生成方式:MD5(api_key+call_id+method+secret_key))
  strcpy(bd_sig,api_key);
  strcpy(bd_sig,timeOfSecond);
  strcpy(bd_sig,method);
  strcpy(bd_sig,secret_key);
  lr_save_string((char*)Calculate(bd_sig,strlen(bd_sig)), "MD5");
  //lr_output_message("%s", md5);
  web_reg_save_param("return_code","LB=error_code\":\"","RB=\"","Search=Body","Ord=1",LAST);
  lr_start_transaction("selectGas");
  web_custom_request("t1",
    "URL=http://192.168.21.67:8080/openapi/datacenter?api_key=zhangdanzhongxin&method=datacenter.getBillGas&call_id={call_id}&bd_sig={MD5}&format=json&req_charset=utf-8"
    "&mobile=13800138000&period=201404"
    "&result_fields=All",
    "Method=GET",
    "Snapshot=t1.inf",
    "Mode=HTML",
    LAST);
  lr_end_reansaction("selectGas", LR_AUTO);
  //业务确定是否成功
  if(strcmp(lr_eval_string("{return_code}"),"0") && strcmp(lr_eval_string("{return_code}"),"300"))//比较函数,C语言中比较只能用函数
{
    lr_error_message("no 0 or 300, is %s, EXIT",lr_eval_string("{return_code}"));
    return -1;
  }
  lr_output_message("********************");
}

乱码出现:web_reg_save_param("error_code","LB=error_msg\":\"","RB=\"","Search=Body","Ord=1",LAST);
使用另外函数单独处理乱码:lr_convert_string_encoding(lr_eval_string("{error_code}"),
LR_ENC_UTF8,LR_ENC_UNICODE,"stringInUnicode");
lr_output_message("%s",lr_eval_string("{stringInUnicode}"));

如果由format=json变成format=xml,就需要调取web_reg_save_param_xpath();
tree模式对于xml模式支持比较好可以方便查看。
web_reg_save_param_xpath("ParamName=return_code","QueryString=//response/error_code",SEARCH_FILTERS,"Scope=Body",LAST);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章