tcp_tw_recycle 慎用
有一次线上问题,表现为有些设备有时能连上,有时又不行,某些设备又一直能连上。
后来经过长时间跟踪,发现是因为开启了tcp_tw_recycle,导致tcp握手异常。
tcp_tw_recycle 介绍
net.ipv4.tcp_tw_recycle
是 Linux 内核中的一个 TCP 参数,用于加速 TCP TIME-WAIT 状态套接字的回收。在打开该选项时,内核会更快地回收处于 TIME-WAIT 状态的连接,以便可以更快地重新使用这些连接资源。
参数说明
net.ipv4.tcp_tw_recycle
:该选项启用(1)或禁用(0)快速回收 TIME-WAIT 状态的套接字。
打开该选项的影响
优点
- 减少 TIME-WAIT 连接:加快 TIME-WAIT 状态套接字的回收,可以减少大量短连接时产生的 TIME-WAIT 状态连接数。
- 提高端口重用率:有助于在高并发连接场景下提高端口的重用率,减轻服务器压力。
缺点
- NAT 兼容性问题 :
tcp_tw_recycle
会严格检查连接的时间戳,这对于 NAT(网络地址转换)环境可能导致严重问题。因为不同的客户端可能会通过同一个 NAT 设备进行连接,这些客户端的时间戳可能不一致,从而导致连接被拒绝。 - 时间戳相关问题:打开该选项后,内核会检查 TCP 时间戳以便判断连接是否可以回收,这可能导致对使用 NAT 的客户端(如移动设备或同一局域网内的多个设备)产生访问问题。
使用 tcp_tw_recycle
的问题场景
- NAT 环境下的问题 :如果你的服务有大量客户端通过 NAT 设备连接,例如通过家庭路由器或公司防火墙连接到互联网,开启
tcp_tw_recycle
可能会导致这些客户端的连接被拒绝,表现为连接超时或无法建立连接。
在 NAT(网络地址转换)环境中,多个客户端可能共享同一个 IP 地址。当这些客户端同时与服务器建立 TCP 连接时,服务器看到的源 IP 地址是相同的。如果 tcp_tw_recycle 被启用,并且同时 tcp_timestamps(默认情况下是启用的)也被启用,服务器可能会因为时间戳的不同而错误地识别连接,导致连接被拒绝或断开。这是因为 tcp_tw_recycle 和 tcp_timestamps 一起使用时,会基于时间戳来区分不同的连接,但在 NAT 环境中,这些时间戳可能不是唯一的。
连接不稳定:启用 tcp_tw_recycle 可能会导致连接不稳定。由于该参数会尝试更快地回收 TIME-WAIT 状态的连接,这可能会干扰正常的 TCP 连接过程,导致连接被拒绝或断开。特别是在高并发或网络状况不佳的情况下,这种不稳定性可能会更加明显。
与某些应用程序或服务的兼容性问题:某些应用程序或服务可能依赖于特定的 TCP 行为。启用 tcp_tw_recycle 可能会改变这些行为,导致与这些应用程序或服务的兼容性问题。
- 现代内核弃用 :在 Linux 内核 4.12 及更高版本中,该选项已经被移除,因为它带来的问题多于好处。代替方案是使用
tcp_tw_reuse
参数。
推荐做法
- 禁用
tcp_tw_recycle
:在大多数情况下,尤其是涉及 NAT 的环境,建议不要启用tcp_tw_recycle
。 - 启用
tcp_tw_reuse
:如果需要优化 TIME-WAIT 状态的连接,建议使用net.ipv4.tcp_tw_reuse
参数,它在安全性和兼容性方面更为合理。