服务器端的许多TIME_WAIT的成本是多少?

时间:2009-11-26 13:05:31

标签: tcp time-wait

假设有一个客户端与服务器建立了很多短生命的连接。

如果客户端关闭连接,则客户端上将有许多TIME_WAIT状态的端口。由于客户端耗尽了本地端口,因此无法快速进行新的连接尝试。

如果服务器关闭了连接,我会在服务器端看到很多TIME_WAIT。但是,这有什么害处吗?客户端(或其他客户端)可以继续进行连接尝试,因为它永远不会耗尽本地端口,并且TIME_WAIT状态的数量将在服务器端增加。最终会发生什么?有什么不好的事吗? (减速,崩溃,掉线等)。

请注意,我的问题不是“TIME_WAIT的目的是什么?”但是“如果服务器上有这么多TIME_WAIT状态,会发生什么?”我已经知道在TCP / IP中关闭连接时会发生什么,以及为什么需要TIME_WAIT状态。我不是想解决问题,而只是想知道它有什么潜在的问题。

简而言之,我们说netstat -nat | grep :8080 | grep TIME_WAIT | wc -l打印100000。会发生什么? O / S网络堆栈是否会变慢? “打开文件太多”错误?或者,没什么可担心的?

6 个答案:

答案 0 :(得分:55)

TIME_WAIT中的每个套接字都会占用内核中的一些内存,通常比ESTABLISHED套接字少一些但仍然很重要。足够大的数字可能耗尽内核内存,或至少降低性能,因为该内存可用于其他目的。 TIME_WAIT套接字不保存打开的文件描述符(假设它们已正确关闭),因此您不必担心“打开文件太多”错误。

套接字还绑定了特定的src / dst IP地址和端口,因此在TIME_WAIT间隔期间不能重复使用它。 (这是TIME_WAIT状态的预期目的。)除非您需要使用相同的端口对重新连接,否则绑定端口通常不是问题。大多数情况下,一方将使用短暂的端口,只有一侧锚定到一个众所周知的端口。但是,如果您反复频繁地连接相同的两个IP地址,则会有大量TIME_WAIT个套接字耗尽短暂的端口空间。请注意,这仅影响此特定IP地址对,并且不会影响与其他主机的连接建立。

答案 1 :(得分:12)

到目前为止的结果:

即使服务器使用系统调用关闭了套接字,如果它进入TIME_WAIT状态,也不会释放其文件描述符。当TIME_WAIT状态消失时(即在2 * MSL秒之后),文件描述符将被释放。因此,太多TIME_WAIT可能会导致服务器进程中出现“打开文件太多”错误。

我认为O / S TCP / IP堆栈已经使用适当的数据结构(例如散列表)实现,因此TIME_WAIT的总数不应该影响O / S TCP / IP堆栈的性能。只有拥有TIME_WAIT状态套接字的进程(服务器)才会受到影响。

答案 2 :(得分:12)

每个连接都由元组(服务器IP,服务器端口,客户端IP,客户端端口)标识。至关重要的是,TIME_WAIT连接(无论是在服务器端还是在客户端)都占据了这些元组中的一个。

在客户端使用TIME_WAIT,很容易理解为什么你不能再建立连接 - 你没有更多的本地端口。但是,同样的问题也适用于服务器端 - 一旦它在单个客户端的TIME_WAIT状态中有64k连接,它就不能再接受来自该客户端的连接< / em>,因为它无法区分旧连接和新连接之间的区别 - 两个连接都由相同的元组标识。在这种情况下,服务器应该只发送RST来自该客户端的新连接尝试。

答案 3 :(得分:2)

如果从许多不同的客户端IP到服务器IP有很多连接,则可能会遇到连接跟踪表的限制。

检查:

sysctl net.ipv4.netfilter.ip_conntrack_count
sysctl net.ipv4.netfilter.ip_conntrack_max

在所有src ip / port和dest ip / port元组中,您只能在跟踪表中拥有net.ipv4.netfilter.ip_conntrack_max。如果达到此限制,您将在日志中看到一条消息&#34; nf_conntrack:table full,drop packet。&#34;在跟踪表中再次出现空间之前,服务器不会接受新的传入连接。

这个限制可能会在短暂的端口耗尽之前很久就会遇到这种情况。

答案 4 :(得分:0)

在我的场景中,我运行了一个重复调度文件的脚本,我的产品做了一些计算并向客户端发送响应,即客户端正在进行重复的http调用以获取每个文件的响应。当大约150个文件被调度时,套接字端口在我的服务器进入time_wait状态,并在客户端抛出异常,打开一个http连接,即

 Error : [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

结果是我的应用程序被挂起了。我不知道可能是线程已经处于等待状态或发生了什么但我需要终止所有进程或重启我的应用程序以使其再次运行。

我尝试将等待时间减少到30秒,因为它默认为240秒,但它不起作用。

因此,基本上整体影响至关重要,因为它使我的应用程序无响应

答案 5 :(得分:-1)

看起来服务器可能只是耗尽端口来为传入连接分配(在现有TIMED_WAIT的持续时间内) - 这是DOS攻击的一种情况。