操作系统:Windows Server 2008,SP2(在 Amazon EC2 上运行)。
使用 Apache httpd 和 tomcat 服务器 6.02 运行 Web 应用程序并且 Web 服务器具有保持活动设置。
大约有 69,250 个(http 端口 80)+ 15000 个(端口 80 以外)TCP 连接处于 TIME_WAIT 状态(使用 netstat 和 tcpview)。即使在停止 Web 服务器后(等待 24 小时),这些连接似乎也不会关闭
性能监视器计数器:
- TCPv4 活动连接数:145K
- TCPv4 被动连接:475K
- TCPv4 故障连接数:16K
- TCPv4 连接重置:23K
HKEY_LOCAL_MACHINE\System \CurrentControlSet\Services\Tcpip\Parameters
没有 TcpTimedWaitDelay 键,因此值应为默认值(2*MSL,4 分钟)
即使同时有数千个连接请求,为什么 Windows 操作系统最终无法清除它们?
这种情况背后的原因可能是什么?
有没有办法强制关闭所有这些 TIME_WAIT 连接而无需重新启动 Windows 操作系统?
几天后,我们的应用程序停止接受任何新的连接。
答案1
我们也遇到过这个问题。亚马逊似乎找到了根本原因并进行了纠正。以下是他们给我的信息。
嗨,我在下面粘贴了导致此问题的原因的解释。好消息是,我们的工程团队最近已经修复了这个问题。要修复它,您只需停止/启动出现此问题的 Windows Server 2008 实例。再次强调,我说的不是重新启动,这是不同的。停止/启动会导致实例移动到不同的(健康)主机。当这些实例再次启动时,它们将在已修复的主机上运行,因此它们不会再次出现此问题。下面是此问题的工程解释。经过深入调查,我们发现,在大多数可用实例类型上运行 Windows 2008 x64 时,我们发现了一个问题,该问题可能导致 TCP 连接在 TIME_WAIT/CLOSE_WAIT 中停留过长时间(在某些情况下,无限期地保持此状态)。在这些状态下,特定的套接字对仍然不可用,如果积累得足够多,将导致相关端口的端口耗尽。如果发生这种特殊情况,清除相关套接字对的唯一解决方案是重新启动相关实例。我们已确定原因在于 Windows 2008 内核 API 中的计时器函数生成的值,在我们的许多 64 位平台上,该函数偶尔会检索到未来非常遥远的值。这会导致 TCP 套接字对上的时间戳被标记在相当遥远的未来,从而影响 TCP 堆栈。据 Microsoft 称,有一个存储的累积计数器,除非此 API 调用生成的值大于累积值,否则不会更新。最终结果是,在此时间点之后创建的套接字都将被标记在太遥远的未来,直到达到该未来时间。在某些情况下,我们看到这个值位于未来几百天之后,因此套接字对似乎永远停滞了。
答案2
Ryan 的回答是很好的一般性建议,只是它不适用于 Ravi 在 EC2 中遇到的情况。我们也看到了这个问题,无论出于什么原因,Windows 都完全忽略了 TcpTimedWaitDelay,并且从不将套接字从其 TIMED_WAIT 状态中释放出来。
等待没有用……重启应用程序也没有用……我们发现的唯一补救措施是重启操作系统。太丑了。
答案3
我在调试一个单独的问题时偶然发现了这个帖子,但这是一个很少被提及但众所周知的 EC2 上的 Windows 问题。我们曾经有高级支持,并通过该渠道在非公开场合与他们讨论过这个问题,但是这是我们的一个相关问题做过在公共论坛上讨论。
正如其他人提到的,您确实需要开箱即用地调整 Windows 服务器。但是,就像 StopWatch 在上述线程中不起作用一样,TCP/IP 堆栈也使用调用QueryPerformanceCounter
来确定 TCP_TIME_WAIT 周期应该持续的确切时间。问题是,在 EC2 上,他们遇到过并且知道一个问题,该问题QueryPerformanceCounter
会失控,并且可能会返回遥远的未来时间;这并不是说您的 TIME_WAIT 状态被忽略了,而是 TIME_WAIT 的到期时间可能要等到未来几年。在 httpd 设置中运行时,您可以看到一旦遇到该状态,这些僵尸套接字就会快速积累(我们通常认为这是一个离散事件,而不是您慢慢积累僵尸)。
我们所做的是在后台运行一个服务,查询处于 TIME_WAIT 状态的套接字数量,一旦该数量超过某个阈值,我们就会采取行动(重启服务器)。过去 45 秒,有人指出您可以停止/启动服务器来解决问题——我建议您将这两种方法结合起来。
答案4
与 AWS 无关,我们刚刚遇到了这个问题,它似乎是这篇 KB 文章的结果:
http://support.microsoft.com/kb/2553549/en-us
基本上,如果系统运行超过 497 天且未应用修补程序,它就会启动。当然,重新启动可以解决问题 - 我们可能在接下来的 16 个月内都不知道修补程序是否有效,但这可能对任何拥有长期正常运行的服务器的人有所帮助。