lrs_receive函数超时问题

今天写了一个socket的脚本,但是遇到一个问题,就是lrs_receive的值如果和预期的不一样这个函数就会一直读取缓存区的值,如果一直获取不到匹配的内容,就会在这里浪费10秒来做这个无用功,所以这样在分析性能结果的时候就会导致误解,很多的响应时间都会浪费在这里。通过网络查询发现这篇文章写的内容和我遇到的问题有点相似,于是就着手尝试,果然解决了我的难题。

回放的过程中发现脚本回放的很慢,一个脚本在忽略think time的情况下回放竟然需要好几分钟,但事务的响应时间并不长。本以为在generator慢,在controller下会快一些,结果试了一下还是一样。

仔细查看回放log后发现在回放慢的事务中都包含了很长的wasted time,这就是回放慢的原因了。查找资料后才知道是由于录制时接收buffer的大小与回放时接收的buffer大小不同(Mismatch)产生的。LR中当遇到Mismatch时,会重新读取socket中的数据,直到超时为止。这个超时时间默认为10秒,可使用lrs_set_recv_timeout2函数进行修改。当脚本回放时mismatch很多时,自然就慢了,而且这个时间并不计入响应时间,而是计入wasted time。

修改了一些返回长度固定的buffer size,又把lrs_set_recv_timeout2设为5秒后,脚本回放时间大大缩短了,但有些数是据根据请求不同动态返回的,肯定会出现mismatch,暂时就没辙了,不过后面会说到解决办法。


参数化没什么特殊的,不再多说了,要注意的一点就是把原始值替换为参数时,有些数据中间有换行,容易遗漏。

这里主要说说动态关联。

Sockets协议中有3个用于关联的函数,分别是lrs_save_param、lrs_save_param_ex和lrs_save_searched_string。前两个函数都是根据偏移量和查找的数据的长度来定位所需要的数据,所以只适合于返回内容基本固定,只是所需要的数据动态变化,而且长度不变的情况,在本次测试中并不适用。第三个函数是根据左右边界来定位要查找的数据,正是我所需要的。lrs_save_searched_string与web协议中的web_reg_save_param函数作用基本一样,所不同的只是web_reg_save_param要放在需要关联的请求前,而lrs_save_searched_string是放在请求后。具体使用方法就看LR的帮助吧。

做到这一步时,脚本已经可以使用了,下面就开始在controller里进行简单的并发测试了。

并发测试过程中,问题又出现了。在并发情况下,经常会出现返回数据比较大的buffer接收不到,由于做了动态关联,没有接收到数据就导致关联失败,从而导致vuser fail掉。我们先开始以为是lrs_set_recv_timeout2设的太短,可是设为120秒情况依旧。仔细看了下lrs_receive的帮助才发现原来还有一个超时时间的设置,这个超时是从发出请求后等待返回数据的时间,使用lrs_set_recv_timeout进行设置,默认同样为10秒。把这个超时时间改为120秒,问题马上就消失了。

在查找问题的过程中,我们又发现了一个函数——lrs_set_receive_option,这个函数可以设置何时停止接收数据,有两种方式:Mismatch(不匹配)和EndMarker(结束符)。默认情况下是Mismatch起作用,Mismatch的默认值为MISMATCH_SIZE,也就是当buffer大小不同时停止接收,然后再重新读取buffer直到超时,从而产生wasted time。所以我就考虑使用EndMarker是否能解决这一问题,把所有动态返回的buffer都使用EndMarker选项进行接收后,果然不再出现wasted time了。

至此,这次测试中使用Sockets协议遇到的问题全部解决了


int i=0;
lrs_send("socket1", "buf220", LrsLastArg);
while( i!=68087)
{  
lrs_receive("socket1", "buf221", LrsLastArg);
i=lrs_get_last_received_buffer_size ("socket1");
}

返回的数据是动态的,出现MISMATCH不奇怪,设置一下匹配时间的最大值就可以了!

lrs_set_recv_timeout2().


    另外你这个代码有时通过是因为你接收的包大小刚好跟录制时的一样,即是68087,如果第一次接收的不是68087的话基本上死循环了,因为lrs_receive函数是读缓冲的,读过的缓冲会清掉,就是说第一次读的缓冲其实已经读了,不过大小不一致而已,那么你继续循环读的话根本不可能再读到那个完整的包了(被第一次读时清掉了),于是一直在等.你可以尝试用下面的函数:


lrs_set_receive_option(EndMarker, EndMarker_None ) // 读取直到缓冲结束.
lrs_set_receive_option(EndMarker, StringTerminator , "\r\n") //读取直到"\r\n"符号出现 . 你可以根据自己的接收数据的结束符修改
lrs_set_receive_option(EndMarker, BinaryStringTerminator , "\\X00") 读取直到二进制符号"\\X00"出现


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值