如何排察一个性能问题的过程

能测试 1.       背景介绍 这个是一个以NETTY为框架开发的聊天系统,主要服务于其它系统的一个内嵌子系统。基于TCP/IP协议的二次定制。在测试一个推送功能的时候。发现压力机上传输出的数据...

attachments-2017-03-Bq67i6J058b8c5a0532a能测试


1.       背景介绍

这个是一个以NETTY为框架开发的聊天系统,主要服务于其它系统的一个内嵌子系统。基于TCP/IP协议的二次定制。在测试一个推送功能的时候。发现压力机上传输出的数据假如有10W条,那么最终入库的时候只有6W条左右的数据。中间过程没有发生任何错误。由于这个一个不需要返回的过程(只负责推送,不确认服务器是否收到),所以无法以检查点来判断。那么这些丢失的数据去哪了?

 


2.       排察过程:


既然是服务端的数据少了。那么看下服务端收到了多少条数据吧,通过统计服务器日志中的信息,确认服务端确实只接收到了6W多的数据:

attachments-2017-03-Y4bli87p58b8c5a888ab

这里有12W,是因为这条信息会打印两次,所以实现收的只有6W多。


     既然系统收到的是这么多,是不是系统程序弄丢的?但是不能直接和开发说你们的程序有问题吧,Netty的框架还是比较成熟的,不太可能会有这样的问题。首先先确认下压力机是否真实发送了这么多的数据,对压力机的网卡做了如下监控:

attachments-2017-03-ADBdJlLr58b8c5b6827b


    可以看出,通过压力机网卡的包数量与LR上显示的数据基本一致(有误差是因为两边启动不同步,且还有其它因素的干扰,但可以忽略)。也就证明了发送端是没有问题的。


     和开发沟通,他们还是感觉不是程序的问题,还是那句话,Netty的框架还是比较成熟的,百度了一下,网上也没有相关的BUG说明。那么就继续找问题吧。


数据会不会在网络传输上丢失了?因为是在局域网内,好像也不会存在这么严重的丢包率。为了验证问题,我们监控服务器的网卡,看看是否达到服务器的数据是否准确:


attachments-2017-03-ZzoXwJb158b8c5e92092

 


可以看出,到达服务器网卡的数量是对的。数据仿佛真的是应用程序弄丢的。经过反复的排察,发现数据总在接近7W的时候开始出现这种情况,之前都是正常的。是哪里有这个限制呢?


 


3.       头脑风暴


组织相关人员,一起来商讨这个问题,从最开始的脚本开发入手。一个一个环节的分析。首先是性能测试脚本的编程。使用的是LRSocket协议,使用长连接,来发送报文,完成后关闭连接。这个看起来也是没错的。在测试其它功能的时候也是正常的(比如测试登录、测试聊天等等都是这种模式,没出现过类似的问题。虽然由于性能问题,TPS不是很乐观,但是数据是不会丢的)。是Netty框架的问题,好像也不是,首先还是说明Netty是个成熟的框架了,不应该会出现这种问题。


于是把这个推送的功能单独拿出来分析。经过一翻讨论和对比,发现推送这个功能最特殊的地方就是它不需要返回报文来确认结果,其它功能都需要返回一个ACK包来确认其结果,会不会是这个地方有我们没注意的东西呢?


 


4.       找资料


于是我们开始各种找资料,学习TCP/IP协议以及与之相关的网卡的工作原理。因为都是较为底层的东西 。最终确认了问题的所在。TCP对于流量的控制机制导致的问题。相关资料如下:


TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。


TCP连接阶段,双方协商窗口尺寸,同时接收方预留数据缓存区;发送方根据协商的结果,发送符合窗口尺寸的数据字节流,并等待对方的确认;发送方根据确认信息,改变窗口的尺寸,增加或者减少发送未得到确认的字节流中的字节数。调整过程包括:如果出现发送拥塞,发送窗口缩小为原来的一半,同时将超时重传的时间间隔扩大一倍。


为什么要有滑动窗口?
1
H1第一次只发送出一个数据包。


2)为什么不一次发送完所有数据包?


在英特网中,可能同时存在着数百万条TCP连接。如果这些连接同时无节制的发送数据包,那么整个网络都会被堵死,没有数据包能到达目的地。


因此TCP需要根据网络状况,每次发送若干数据包。


 


 简单来说,网卡在控制流量的时候,会有一个缓存机制,当接收的量大于传送给应用程的量时,网卡会把数据缓冲在一个类似于缓冲区的地方。利用滑动窗口机制来控制传输。这时候需要确保这个TCP连接是存在的,对会启动滑动窗口机制。当连接断开后,由于物理链路的丢失,这部分“缓冲”数据也会跟着消失。


(这部分可能说的不是很清楚,请自行百度TCP控制流量的规则及滑动窗口机制)


 


 


5.       最终解释及解决办法


   明白了网卡的工作原理后,就可以解释上面的现象了。由于我们大量发送数据,服务器的网卡在接收这些数据后,往应用层传送数据时,启动了滑动窗口机制,对一部分数据做了“缓冲”。但这些数据是全部达到网卡这一层的,所以我们的监控也没有问题,因为数据确实是到达了网卡。但是由于这个功能没有确认机制,客户端发送完数据后,就关闭了连接。导致网卡“缓冲区”里的数据不知道往哪送了。所以数据就丢了,因为数据也没有到达应用层,所以应用层日志时也没有错误。


让运维的大牛帮我们修改过内核参数后(调整滑动窗口的大小),经验证,如果不让连接保持,那个数据丢失的量会减少。证明了我们的猜想是正确的。


解决办法:客户端发送完消息后,不要马上断开连接,先保持一段时间,让服务端网卡里缓冲区的数据“知道”往哪走,问题就消失了。


 


6.       小结


   在这个问题的处理上可以看出,性能测试涉及到方方面面,不但要懂软件,还要懂硬件。在解决了这个问题之后,我们就能更清楚的知道网络是怎么处理等待的,为什么带宽满了后响应时间会变长。对这些问题有了更深的了解。


另:为什么其它功能不会出现此问题。是因为其它的情况下,我们需要一个ACK的返回包来确认我们的结果。所以在没有得到结果之前,连接是会一直保持着的。所以在测试Socket之上的协议时,基本不会出现此问题,但是越底层的协议越需要注意这些细节。同时这个问题也可以解释为什么在同样的压力下,网络的好坏也会影响响应时间(网络较差时,数据在“缓冲区”时的时间会越长,容易超时,导致数连断开,客户端产生超时的现象)。


  • 发表于 2017-03-03 09:26
  • 阅读 ( 457 )
  • 分类:性能测试

你可能感兴趣的文章

相关问题

1 条评论

请先 登录 后评论

分享

立送30金币

Loadrunner技能提升ROAD