我一直在调查我的 Web 服务器 (Web01) 和数据库服务器 (Database01) 之间的连接问题。我当前的设置:
Web01 - 两个 NIC,一个是外部的(有防火墙),一个是内部的(没有防火墙)。Database01
- 与上述配置相同。
两台服务器使用私有 NIC 进行通信,因此防火墙配置文件被禁用。我发现,在 Web01 上出现两个错误:
WEB01: A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)
或者
WEB01: The wait operation timed out
这并不一致,尽管当我在 Web01 上运行爬网(通过 Xenu)来爬取新网站时,它们更有可能发生。
在 Database01 上,我已经识别出来自 Windows 过滤平台的一系列消息:
DATABASE01: The Windows Filtering Platform has blocked a packet.
研究这个,它的沉默端口扫描预防过滤器内置于 Windows 防火墙中。无论专用配置文件(用于专用 NIC)是否已关闭,此功能都会运行。
此功能的目的是拦截没有连接侦听器的端口的请求并拒绝数据包。
问题在于,有问题的端口是默认的 sql server 端口,1433
而 sql server是聽。
所以我的问题是,在什么其他情况下防火墙会以这种方式丢弃数据包。
其他评论/可能的问题/说明:
- 我正在使用 Entity Framework 和 Autofac,并且我的上下文使用按请求生命周期范围。这应该确保在每个请求结束时关闭并处置连接,但在内部,这实现了一个工作单元模型,因此我希望每个批处理操作都会打开和关闭连接,因此不应该等待任何可能长时间运行的请求结束。
- ASP.NET 的数据库池配置尚未更改,因此连接生存期和连接池大小都设置为默认值。
- 连接字符串最初仅指定服务器名称,因此是默认实例:
server=database01
,但为了消除 Sql Server Browser 服务的任何潜在问题,我修改了连接字符串以server=tcp:database01,1433
强制使用 TCP 连接(因此它不必尝试共享内存或命名管道),并且已准确指定端口(因此它不需要先查询浏览器服务来识别正确的端口)。 - Database01 确实充当数据库镜像的主体(作为具有自动故障转移功能的 2 服务器镜像解决方案的一部分,Database02 作为合作伙伴,运行 SQL Server Express 的 Web01 作为见证服务器)。我已禁用目标数据库的镜像,但问题仍然存在。
- 我已经确认正在使用该命令
sqlserver.exe
监听端口,并且可以看到它的绑定如下:1433
netstat -anob -p tcp
netstat -anob -p tcp
TCP 0.0.0.0:1433 0.0.0.0:0 LISTENING 1896
TCP 192.168.3.2:1433 192.168.3.2:49274 ESTABLISHED 1896
以上结果中,192.168.3.2 是 Database01 的私有 IP,192.168.3.1 是 Web01 的私有 IP,外部端口 49274 由 ASP.NET 连接池动态分配。
我已尝试尽可能地消除问题,但仍然无法确定问题的根本原因:
为什么 Windows 防火墙会丢弃正在监听的端口的数据包?
Web01:Windows Server 2012 R2 标准 64 位
数据库01:Windows Server 2012 64位 SQL Server 2012 SP1 标准版
答案1
这个问题的解决方案是一个名为“TCP 卸载”的功能。我不确定这是否是因为我在虚拟化环境中运行,但 TCP 卸载导致了数据包丢失。当此功能已禁用丢失的数据包似乎确实消失了。
TCP 卸载通过以下方式消除了 CPU 处理网络 I/O 的负担:卸载将其安装到 NIC 上。
我确实想知道如果我运行硬件环境是否仍然会出现这个问题。
https://support.rackspace.com/how-to/disabling-tcp-offloading-in-windows-server-2012/