linux开启tcp_tw_recycle引发的问题总结
时间:2023-02-17 18:07:02.425 +0800 CST 浏览:312

存在场景

服务端

cat /etc/sysctl.conf
...
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 1
...

客户端

k8s集群pod中请求服务端的http接口

客户端host抓包

tcpdump -i bond0  host 10.1.xxx.xxx and port 80 -nnA -w  xxx.pcap

通过抓包发现是服务端没有返回SYN,ACK

问题原因

tcp_tw_recycle参数。它用来快速回收TIME_WAIT连接,不过如果在NAT环境下会引发问题。
RFC1323中有如下一段描述:

An additional mechanism could be added to the TCP, a per-host cache of the last timestamp received from any connection. This value could then be used in the PAWS mechanism to reject old duplicate segments from earlier incarnations of the connection, if the timestamp clock can be guaranteed to have ticked at least once since the old connection was open. This would require that the TIME-WAIT delay plus the RTT together must be at least one tick of the sender’s timestamp clock. Such an extension is not part of the proposal of this RFC.

  • 大概意思是说TCP有一种行为,可以缓存每个连接最新的时间戳,后续请求中如果时间戳小于缓存的时间戳,即视为无效,相应的数据包会被丢弃。
  • Linux是否启用这种行为取决于tcp_timestampstcp_tw_recycle,因为tcp_timestamps缺省就是开启的,所以当tcp_tw_recycle被开启后,实际上这种行为就被激活了,当客户端或服务端以NAT方式构建的时候就可能出现问题,下面以客户端NAT为例来说明:
  • 当多个客户端通过NAT方式联网并与服务端交互时,服务端看到的是同一个IP,也就是说对服务端而言这些客户端实际上等同于一个,可惜由于这些客户端的时间戳可能存在差异,于是乎从服务端的视角看,便可能出现时间戳错乱的现象,进而直接导致时间戳小的数据包被丢弃。如果发生了此类问题,具体的表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK。

解决方法

cat /etc/sysctl.conf
...
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 262144
...
  • 关闭tcp_tw_recycle
  • 打开tcp_tw_reuse(允许将TIME-WAIT sockets重新用于新的TCP连接)
  • tcp_max_tw_buckets对应的是系统同时保持的TIME_WAIT的最大数量,不宜设置过小,超过这个数量将会导致部分连接异常或者新的连接建立失败

总结

当有大量的TIME-WAIT时,不建议开启tcp_tw_recycle,上面也说到了会在NAT环境中导致请求失败, 而且在4.12之后的内核已移除tcp_tw_recycle内核参数。

参考:

https://cloud.tencent.com/developer/article/1443327



如果这篇文章对你有所帮助,可以通过下边的“打赏”功能进行小额的打赏。

本网站部分内容来源于互联网,如有侵犯版权请来信告知,我们将立即处理。


来说两句吧