总结自己的系统性能瓶颈定位和性能调优方法,建立一个粗略的分析模型。
在进行分析时,对于产生的问题,可以从3方面入手分析:
包括测试工具本身固有的缺陷和测试机器资源问题,在测试中都有可能导致用例失败情况。所以,好的测试人员,需要对使用的工具很熟悉,了解该工具的优点和缺陷,扬长避短。反之,如果不熟悉工具的缺陷,将会对问题的真正来源产生错误判断。
比如JMeter等性能测试工具,每一个agent都存在一个可支持的最大线程数,一旦使用远大于该数目的线程,可能会大量产生socket错误。那么,对于不了解这种情况的测试人员,就可能认为是服务端产生了问题。我们应该避免这种情况。
同时,需要了解测试机器本身资源对测试工具的支持情况,包括CPU和内存,甚至socket资源等。可以预先计算或试验出测试机器所能支持的最大socket线程数,在测试执行时,分配小于该数目的线程数,以避免因测试机器资源紧张产生用例失败。
分析测试端、服务端之间网络连接是否存在带宽不足、有时延等通信问题。
.
下面对于网络错误可能的原因进行分析,并给出配置方法,通过该方法,进行配置调优,并进行重复测试,确认性能有提升:
1)、由于socket的listen队列太小,而导致socket连接产生大量超时错误、重连接错误
在Linux下,修改AF_INET类型socket的listen队列长度SOMAXCONN:
方法:
在/etc/sysctl.conf增加选项:net.core.somaxconn=32768
sysctl -p /etc/sysctl.conf
所有服务器执行,加载时无报错即可。
解释:
该配置用于解除函数int listen(int sockfd, int backlog)的一个BUG,增加net.core.somaxconn=32768语句后,SOMAXCONN的值将由原缺省的128更改为32768。
该设置可用于定位并解决性能测试中(以JMeter为例),由于有大并发量的HTTP请求而造成返回non HTTP Response:connect time out错误的情况。
参考:
http://hi.baidu.com/mfktafd/item/79731d32c4ca0684c3cf2911
BUGS
If the socket is of type AF_INET, and the backlog argument is greater than the constant SOMAXCONN (128 in Linux 2.0 & 2.2), it is silently trun-
cated to SOMAXCONN.
2)、由于linux进程可创建的socket数受限,而导致socket连接产生大量超时错误
方法:
step1:
vi /etc/sysctl.conf
#增加选项
fs.file-max=102400
#完成上述增加后运行,不出错即可。
sysctl -p /etc/sysctl.conf
step2:
vi /etc/security/limits.conf
#增加软限制和硬限制
* soft nofile 102400
* hard nofile 102400
退出重新登录后,通过ulimit -n可以看到修改已经生效。
解释:
用于解决因为进程可以打开的最大socket数有限,当有大量并发HTTP请求过来时,导致出现connection time out错误。
使用ulimit -n修改只对当前登录到linux的会话有效,除非在上面运行linux版本的JMeter(或其他),否则在windows上运行的JMeter发起的线程数仍然限制在ulimit修改前的值。
修改/etc/security/limits.conf对所有登录会话均有效。
参考:
http://blog.csdn.net/ajupiter/article/details/9273887
3)、由于服务程序或客户端程序没有及时关闭socket(通过调用closesocket),而导致服务器产生大量状态为CLOST_WAIT,TIME_WAIT的TCP连接:
根据socket关闭流程(3步握手),在服务端和客户端之间,至少需要发送4个分组(packet),socket连接才能正常关闭。流程如下:
Server [FIN_WAIT_1] --------FIN-------> Client[CLOSE_WAIT]
Server [FIN_WAIT_2] <--------ACK------- Client
Server <--------FIN-------- Client[LAST_ACK]
Server[TIME_WAIT] --------ACK-------> Client[CLOSED]
如果client有大量的tcp连接处于CLOSE_WAIT状态,说明client没有对收到的FIN分组进行处理(属于程序BUG)。注意:上面Client发给Server的ACK分组是TCP自动回复的。
如果server有大量的tcp连接处于TIME_WAIT状态,说明server已经收到客户端发送的ack和fin分组。该状态会持续2MSL(MSL:Max Segment Lifetime)长时间,该时间内,socket不能回收使用(指定相同ip、端口的socket)。这是正常的现象,但是如果TIME_WAIT过大,也可能会导致这段时间内服务不可用。因此需要修改TIME_WAIT时间到合适大小。
方法:
修改程序bug:客户端程序使用完连接后,要及时关闭;注意在服务端发送FIN分组过来后,要关闭socket。
修改服务器:如下,修改time_wait时间:
vi /etc/sysctl.conf
编辑文件,加入以下内容,将TIME_WAIT时间改为30秒:
net.ipv4.tcp_fin_timeout = 30
然后执行
/sbin/sysctl -p
让参数生效。
解释:
客户端如果在使用大量tcp连接后,未及时关闭,可能在服务端会产生大量的TIME_WAIT状态的TCP连接。
同时,服务端的TIME_WAIT时间需要设置到合适大小,保证服务。
参考:
http://kerry.blog.51cto.com/172631/105233/
4)、测试机器缺失注册表项MaxUserPort、TcpTimedWaitDelay,或设置不恰当值造成的错误(在JMeter中是address already in use)
方法:
在运行JMeter agent的机器上上添加注册表条目MaxUserPort和TcpTimedWaitDelay,分别设置值为65534、30,以增大可分配的tcp连接端口数,减少处于TIME_WAIT状态的连接的有效时间。
该方法确定对XP有效,可能对Windows Server也有效。因为在Windows Server 2003 R2上发现缺失MaxUserPort和TcpTimedWaitDelay。具体设置,见下面的连接。
参考:
http://twit88.com/blog/2008/07/28/jmeter-exception-javanetbindexception-address-already-in-use-connect/