[关闭]
@gy-ban 2017-05-30T07:55:09.000000Z 字数 2004 阅读 695

记一次time wait bucket table overflow 解决方法

linux


最近在巡视服务器的时候,发现有几台服务器的dmesg有很多的time wait bucket table overflow 报错。一开始也不知道这是什么报错,于是就上网查了下。

其实解决方法很简单,只要修改net.ipv4.tcp_max_tw_buckets这个内核参数就可以了,原因是TIME_WAIT连接超出了限制,使用netstat -an | awk '{print $6}' | sort | uniq -c | sort -rn 命令查看。但是对于问题的实质我们却完全没有搞清楚。
首先我们得要清楚TIME_WAIT是怎么产生的,这就得说说TCP的四次握手释放连接

TCP 释放连接的过程

A运行的是TCP客户端进程,而B运行的是TCP服务端进程。最开始的时候两端的TCP进程都处于ESTABLISHED(已建立连接)状态。
这时候,A主动关闭,请求释放连接。
(1)第一次握手 A→ B
A的TCP客户进程向B发出释放连接请求报文段,其中FIN(终止位)=1,seq(序号)=u。
TCP规定,当报文段的FIN=1时,表明此报文段的发送方的数据已发生完毕,并要求释放连接;FIN报文段(FIN=1的报文段)不能携带数据,但是要消耗掉一个序号。
在A发送完毕之后,A的TCP客户端进程进入FIN-WAIT-1(终止等待1)状态。

(2)第二次握手 B→A
B在收到连接释放连接请求报文段之后,随即向A发送确认报文段。其中ACK=1,seq=v,ack(确认号)=u+1。
在B发送完毕之后,B的TCP服务端进程进入CLOSE-WAIT(关闭等待)状态。
TCP服务器进程这时应该通知高层应用经常,从A到B这个方向的连接就要释放了,这时的TCP连接处于半关闭(half-close)状态。
A在收到B的确认报文段之后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。

(3)第三次握手 B→A
若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。B向A发出释放连接报文段,其中FIN=1,ACK=1,seq=w,ack=u+1。
TCP规定,当报文段的FIN=1时,表明此报文段的发送方的数据已发生完毕,并要求释放连接;FIN报文段(FIN=1的报文段)不能携带数据,但是要消耗掉一个序号。
在B发送完毕之后,B的TCP服务端进程进入LAST-ACK(最后确认)状态。

(4)第四次握手 A→B
A在接收到B的释放连接请求报文段之后,必须对此发出确认。其中ACK=1,seq=u+1,ack=w+1。
A在发送完毕之后,进入到TIME-WAIT(时间等待)状态。B在接收到A的确认之后,进入到CLOSED(关闭)状态。
在经过时间等待计时器设置的时间2MSL之后,A才进入到CLOSED状态。

从上面的过程中我们知道

TIME_WAIT的产生条件

主动关闭方在发送四次挥手的最后一个ACK会变为TIME_WAIT状态,保留次状态的时间为两个MSL(linux里一个MSL为30s,是不可配置的)

TIME_WAIT两个MSL的作用

可靠安全的关闭TCP连接。比如网络拥塞,主动方最后一个ACK被动方没收到,这时被动方会对FIN开启TCP重传,发送多个FIN包,在这时尚未关闭的TIME_WAIT就会把这些尾巴问题处理掉,不至于对新连接及其它服务产生影响。

TIME_WAIT占用的资源

少量内存(查资料大概4K)和一个fd。

TIME_WAIT关闭的危害

1、 网络情况不好时,如果主动方无TIME_WAIT等待,关闭前个连接后,主动方与被动方又建立起新的TCP连接,这时被动方重传或延时过来的FIN包过来后会直接影响新的TCP连接;
2、 同样网络情况不好并且无TIME_WAIT等待,关闭连接后无新连接,当接收到被动方重传或延迟的FIN包后,会给被动方回一个RST包,可能会影响被动方其它的服务连接。

TCP: time wait bucket table overflow产生原因及影响

原因是超过了linux系统tw数量的阀值。
危害是超过阀值后﹐系统会把多余的time-wait socket 删除掉,并且显示警告信息,如果是NAT网络环境又存在大量访问,会产生各种连接不稳定断开的情况

net.ipv4.tcp_max_tw_buckets

net.ipv4.tcp_max_tw_buckets是控制系统允许处于TIME_WAIT状态的套接字(Sockets)的最大数,这个限制是为了防止Dos(denial-of-service)攻击而存在。默认值是NR_FILE*2,并且会根据系统的内存容量被调整。如果超过net.ipv4.tcp_max_tw_buckets上限,该连接被关闭
修改:/etc/sysct.conf 的net.ipv4.tcp_max_tw_buckets 值,使用sysctl -p 使它生效。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注