关于NAT后端服务端使能TW(Timewait)连接快速回收造成用户连接成功率降低的问题,来捋一捋。
TW的意义
对于主动关闭连接的一方,总是在FIN_WAIT2状态收到FIN并回复ACK(或在FIN_WAIT1收到FIN/ACK并回复ACK),因为回复的ACK无序列号无法得到对端的确认,所以主动关闭一方无法知道最后的ACK是否到达对端。所以主动关闭一端在回复ACK后进入TW状态,保留2MSL时间等待对方重传FIN,保证ACK可靠地到达对端。
另一方面,TW状态下的五元组连接无法被重新建立。如果TW状态下相同五元组连接被新建,那么网络中“迷路”的旧连接报文很可能重新到达,并将新连接FIN关闭或劫持。所以TW状态持续2MSL,保证旧连接报文在网络中消失。
TW状态的连接如僵尸般存在,即无法被重用,又占据着内存,有很多方式去控制TW状态连接数量,如设置tcp_max_tw_buckets内核选项控制系统TW状态连接最大值,或使能linger选项让连接在关闭时直接RST,但这样的方式不优雅也不安全。
Linux通过tcp_tw_reuse和tcp_tw_recycle内核选项控制TW连接的复用。期望TW连接的复用,就需要解决新旧连接报文区分的问题,防止旧连接报文对新连接的劫持。Linux的tcp_tw_reuse或tcp_tw_recycle功能使能需同时开启tcp_timestamps时间戳,在旧连接关闭时,记录旧连接最后到来报文的时间戳,以此为标准区别新旧连接报文,时间戳小于该记录值的报文被判定为旧连接报文,旧连接报文将被丢弃,而新连接报文允许TW连接的服用。
其中,tcp_tw_reuse为连接重用,即连接仍处于TW状态