关于内核参数tcp_tw_recycle

最近上线了一个手机类的网站,发现测试中苹果和安卓的系统访问效果区别很大。安卓系统访问的时候速度明显比较慢。然后进行排查,

当时环境是网站跑在系统是centos 5的虚拟机,物理机是centos 6 。考虑到是不是网络参数的问题,所以修改了tcp_tw_recycle,改完以后发现问题得到解决。

初步判断是由于centos 5 和 6  以及安卓系统对tcp链接中的信息不同导致的,ios系统不存在该问题。

如果服务器在负载均衡器后面,同时这个负载均衡器做了NAT且不改变数据包的timestamp,那么有可能导致某个客户端发出的syn包被丢弃,造成连接请求超时。因为timestamp的值来自于源机器的jiffies。不同的机器开机时间很难是完全相同的。此时,除了客户端请求超时外,在服务器上还可以观察到netstat -s的结果里passive connections rejected by timestamp这一行的数值在增长。


当满足下面所有的条件时,这个syn包将会被丢弃,然后释放相关内存,并发送rst。
1 tcp的option有 time stamp字段.
2 tcp_tw_recycle有设置。
3 在路由表中是否存在完全相同的流(如果打开了xfrm的话,还要比较端口,默认xfrm应该是打开的),如果存在则直接返回.
4 并且数据包的源地址和新请求的源地址相同.
5 根据路由表以及源地址能够查找到保存的peer(这个可以看我以前的blog,也就是保存了一些连接统计信息).
6 当前时间(接收到syn)比最后一次的时间(time stamp)小于60秒.
7 已经存在peer的最近一次时间戳要大于当前请求进来的时间戳.
从上面可以看到,上面的条件中1/2都是 server端可以控制的,而其他的条件,都是很容易就满足的,因此我们举个例子。
如果客户端是NAT出来的,并且我们server端有打开tcp_tw_recycle ,并且time stamp也没有关闭,那么假设第一个连接进来,然后关闭,此时这个句柄处于time wait状态,然后很快(小于60秒)又一个客户端(相同的源地址,如果打开了xfrm还要相同的端口号)发一个syn包,此时linux内核就会认为这个数据包异常的,因此就会丢掉这个包,并发送rst。
而现在大部分的客户端都是NAT出来的,因此建议tw_recycle还是关闭,或者说server段关闭掉time stamp(/proc/sys/net/ipv4/tcp_timestamps).

你可能感兴趣的:(关于内核参数tcp_tw_recycle)