获取系统缺少足够的缓冲区空间或因为队列已满

use*_*567 5 asp.net windows-server-2008-r2 netstat

我的 ASP.NET 和 SQL Server 2012 应用程序在 Windows Server 2008 R2 上运行。突然,我在服务器上的互联网停止工作,我的应用程序开始抛出,

An operation on a socket could not be performed because the system lacked sufficient buffer 
space or because a queue was full
Run Code Online (Sandbox Code Playgroud)

运行 netstat 显示 PID = 0 打开了很多端口。Netstat 说,

Process Id = 0, State = TIME_WAIT have 130,053 ports open
Process Id = 38840, State = CLOSE_WAIT have 5 ports open
Process Id = Any, State = LISTENING have 30 ports open
Process Id = Any, State = ESTABLISHED have 10 ports open
Run Code Online (Sandbox Code Playgroud)

2015 年 12 月 22 日统计,

CLOSE_WAIT  5   
ESTABLISHED 146
TIME_WAIT   646750
LAST_ACK    1
LISTENING   30
Run Code Online (Sandbox Code Playgroud)

har*_*ymc 7

您正在运行可通过多个移动设备的浏览器访问的 Web 服务器。

由于 TCP/IP 的工作方式,连接不能立即关闭。数据包可能无序到达或在连接关闭后重新传输。CLOSE_WAIT 表示远程端点(连接的另一端)已关闭连接。TIME_WAIT 表示本地端点(这边)已经关闭了连接。连接被保留,以便任何延迟的数据包都可以与连接匹配并得到适当的处理。当连接在默认的四分钟时间内超时时,连接将被删除。

然而,TIME_WAIT 统计数据旁边的数字 646750 非常多。这意味着在过去 4 分钟内关闭了 646750 个连接,即每秒 2694 个!显然,其中一些移动设备出现严重故障,并使用未从客户端正确关闭的连接轰炸您的服务器,或者您正在为大量客户端提供服务(这对单个服务器来说毫无意义)。

如果您无法确定导致问题的移动设备或应用程序并修复它们,则您无法控制客户端,只能在服务器端缓解问题。

可以改善这种拥塞的一个参数是TcpTimedWaitDelay,描述为:

确定 TCP 可以释放关闭的连接并重用其资源之前必须经过的时间。关闭和释放之间的间隔称为 TIME_WAIT 状态或 2MSL 状态。在此期间,客户端和服务器可以以比建立新连接少得多的成本重新打开连接。

减少这个条目的值可以让 TCP 更快地释放关闭的连接,为新连接提供更多资源。但是,如果该值太低,TCP 可能会在连接完成之前释放连接资源,从而需要服务器使用额外的资源来重新建立连接。

TcpTimedWaitDelay 可以通过 regedit 修改 HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters。它包含等待的秒数。默认值为 240 秒(4 分钟)。如果更改需要重新启动。

例如,更改为 30 秒和每秒 2694 个连接将意味着只有 80820 个连接等待关闭。这个数字仍然很大,但变化仍然会减少连接资源的使用。