使用 Microsoft 登录
登录或创建帐户。
你好,
使用其他帐户。
你有多个帐户
选择要登录的帐户。

在使用 SQL Server ODBC 驱动程序、SQL Server OLE DB 提供程序或 System.Data.SqlClient 管理提供程序时,可以通过使用各自的应用程序编程接口 (API) 来禁用连接池。当您禁用了连接池后,如果应用程序频繁打开和关闭连接,则可能会增加基础 SQL Server 网络库上的压力。本文介绍了在这些情况下您可能必须要调整的某些 TCP/IP 设置。

概要

关闭连接池可能会导致基础 SQL Server 网络驱动程序频繁打开和关闭新的套接字到运行 SQL Server 的计算机的连接。您可能必须为操作系统和运行 SQL Server 的计算机更改默认 TCP/IP 套接字设置,以便处理压力较大这一问题。

注意,本文只讨论使用 TCP/IP 协议时影响 SQL Server 网络库的那些设置。关闭连接池还会给其他 SQL Server 协议(如命名管道)同样带来与压力相关的问题,但本文不讨论这一主题。本文只针对高级用户。如果您对本文的主题不理解,Microsoft 建议您读一本合适的关于 TCP/IP 套接字的书。

注意,Microsoft 强烈建议让 SQL Server 驱动程序总使用连接池功能。在使用 SQL Server 驱动程序时,使用连接池功能可极大地提高客户端和 SQL Server 端的总体性能。使用连接池还可以显著减少到运行 SQL Server 的计算机的网络通讯量。例如,在一个示例性测试中,有 20,000 个 SQL Server 连接的打开和关闭,在启用连接池时,此过程使用了大约 160 个 TCP/IP 网络数据包,传递了总共 23,520 字节的网络活动。在禁用连接池时,同一示例性测试却生成了 225,129 个 TCP/IP 网络数据包,传递了总共 27,209,622 字节的网络活动。

注意,当您看到 SQL Server 网络库出现这些与压力相关的 TCP/IP 套接字问题时,在您尝试连接到运行 SQL Server 的计算机时可能会收到下面的一条或多条错误消息:

SQL Server 不存在或访问被拒绝

已超时

常规网络错误

注意,当 SQL Server 发生其他问题时,您也可能会收到这些特定的错误消息;例如,在下列情况下您都可能会收到这些错误消息:运行 SQL Server 的远程计算机关闭、运行 SQL Server 的远程计算机根本未侦听 TCP/IP 套接字、到运行 SQL Server 的计算机的连接因网络电缆被拨出而中断,或者存在 DNS 解析问题。一般情况下,任何可导致客户端无法打开到 SQL Server 服务器的 TCP/IP 套接字的问题也会导致出现这些错误消息。不过,对于与压力相关的套接字问题来说,问题的发生是间歇性的,因为压力会时升时降。计算机可能会运行数小时不出现错误,接着出错一两次,然后又好几个小时不出错。而且,当您遇到此问题时,到 SQL Server 的连接时好时坏。也就是说,与压力相关的套接字问题通常具有偶发性,而 SQL Server 的实际网络连接问题通常不是偶发性的。

在使用 SQL Server TCP/IP 协议时如果禁用连接池功能,通常会发生两种主要的与压力相关的问题:在客户端计算机的匿名端口上的空间可能不足,或者在运行 SQL Server 的计算机上可能超过默认 WinsockListenBacklog 设置。


有关匿名端口的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:

319502 PRB:增加 IMAP 连接限制后在尝试通过匿名端口连接时出现“WSAEADDRESSINUSE”错误消息

调整 MaxUserPort 和 TcpTimedWaitDelay 设置

注意,MaxUserPort 和 TcpTimedWaitDelay 设置仅适用于这样的客户端计算机:它频繁打开和关闭到运行 SQL Server 的远程计算机的连接,但未使用连接池。例如,这些设置适用于这样一个 Internet Information Services (IIS) 服务器:它正在服务于大量传入的 HTTP 请求,并频频打开和关闭到运行 SQL Server 的远程计算机的连接,此服务器使用 TCP/IP 协议但禁用了连接池功能。如果启用了连接池,则不必调整 MaxUserPort 和 TcpTimedWaitDelay 设置。

当您使用 TCP/IP 协议打开一个到运行 SQL Server 的计算机的连接时,基础 SQL Server 网络库将打开一个到运行 SQL Server 的计算机的 TCP/IP 套接字。当它打开此套接字时,SQL Server 网络库不启用 SO_REUSEADDR TCP/IP 套接字选项。有关 SO_REUSEADDR 套接字设置的更多信息,请参阅 Microsoft Developer Network (MSDN) 中的“Setsockopt”主题。


注意,出于安全原因,SQL Server 网络库特意不启用 SO_REUSEADDR TCP/IP 套接字选项。当 SO_REUSEADDR 启用时,恶意用户会挟制一个到 SQL Server 的客户端端口并使用客户端提供的凭据获得对运行 SQL Server 的计算机的访问权限。默认情况下,由于 SQL Server 网络库不启用 SO_REUSEADDR 套接字选项,因此您每次通过客户端上的 SQL Server 网络库打开和关闭套接字时,套接字都会进入为时四分钟的 TIME_WAIT 状态。如果您在禁用连接池的情况下频频打开和关闭通过 TCP/IP 的 SQL Server 连接,您实际上就是在频频打开和关闭 TCP/IP 套接字。换句话说,每一个 SQL Server 连接都有一个 TCP/IP 套接字。如果在不到四分钟的时间内快速打开和关闭了 4000 个套接字,就会达到客户端匿名端口的默认最大设置,并且在现有 TIME_WAIT 套接字超时前新的套接字连接尝试将不会成功。

在客户端,当您禁用了连接池时,可能必须增加在 Q319502 中讨论的 MaxUserPort 和 TcpTimedWaitDelay 设置。这些值的设置由客户端上发生的 SQL Server 连接的打开和关闭数量来决定。您可以通过使用客户端计算机上的 Netstat 工具来检查有多少客户端端口处于 TIME_WAIT 状态。按如下所示使用 -n 标志运行 Netstat 工具,并数一数到您的 SQL Server IP 地址的客户端套接字中有多少处于 TIME_WAIT 状态。在此示例中,运行 SQL Server 的远程计算机的 IP 地址是 10.10.10.20,客户端计算机的 IP 地址是 10.10.10.10,有三个已建立的连接,有两个处于 TIME_WAIT 状态的连接:

C:\>netstat -n

Active Connections

Proto Local Address Foreign Address State
TCP 10.10.10.10:2000 10.10.10.20:1433 ESTABLISHED
TCP 10.10.10.10:2001 10.10.10.20:1433 ESTABLISHED
TCP 10.10.10.10:2002 10.10.10.20:1433 ESTABLISHED
TCP 10.10.10.10:2003 10.10.10.20:1433 TIME_WAIT
TCP 10.10.10.10:2004 10.10.10.20:1433 TIME_WAIT

如果您运行 netstat -n 并发现有将近 4000 个到运行 SQL Server 的目标计算机的 IP 地址的连接处于 TIME_WAIT 状态,则可以增加默认 MaxUserPort 设置并同时降低 TcpTimedWaitDelay 设置,以便不会用尽客户端匿名端口。例如,您可以将 MaxUserPort 设置为 20000,将 TcpTimedWaitDelay 设置为 30。较低的 TcpTimedWaitDelay 设置意味着套接字在 TIME_WAIT 状态中等待的时间更短。较高的 MaxUserPort 设置意味着您可以让更多的套接字处于 TIME_WAIT 状态。

注意,如果调整 MaxUserPort 或 TcpTimedWaitDelay 设置,您必须重新启动 Microsoft Windows 以使新设置生效。MaxUserPort 和 TcpTimedWaitDelay 设置适用于任何通过 TCP/IP 套接字与运行 SQL Server 的计算机对话的客户端计算机。如果在运行 SQL Server 的计算机上进行这些设置,它们将不起作用,除非您是在建立本地 TCP/IP 套接字到运行 SQL Server 的本地计算机的连接。

调整 WinsockListenBacklog 设置

有关此特定于 SQL Server 的注册表设置的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:

154628 INF:发生多个 TCP\IP 连接请求时 SQL 记录 17832
默认情况下,SQL Server 使用的 WinsockListenBacklog 设置为 5。这意味着当 Winsock API listen 在运行 SQL Server 的计算机上建立 TCP/IP 协议侦听线程时,运行 SQL Server 的计算机会将值 5 传递给 Winsock API listen 的 backlog 参数。此 backlog 设置是侦听器的等待连接队列的最大长度。超过此队列长度时,其他到运行 SQL Server 的计算机的 TCP/IP 套接字连接尝试将立即被拒绝并收到一个 ACK+RESET 数据包。

backlog 设置的工作过程如下:假定一个任意的服务正在侦听是否有传入的 TCP/IP 套接字请求。如果您将 backlog 设置为 5 并且有许多套接字连接请求源源不断地传入,则此服务对传入请求的响应速度就可能会赶不上请求的传入速度。此时,TCP/IP 套接字层将用 backlog 队列让传入请求排队,此服务稍后可以从此队列中提取请求并处理传入套接字连接请求。队列排满后,TCP/IP 套接字层将立即拒绝任何更多的传入套接字请求,将一个 ACK+RESET 数据包发送回客户端。增加 backlog 队列的大小后,TCP/IP 套接字层可让更多数量的等待套接字连接请求排队,超过此更大的数量后才会开始拒绝请求。

注意,WinsockListenBacklog 设置是特定于 SQL Server 的。SQL Server 服务刚启动时,SQL Server 将尝试读取此注册表设置。如果此设置不存在,则使用默认值 5。如果该注册表设置存在,当为在 SQL Server 内部建立 TCP/IP 套接字侦听线程而调用 WinSock API listen 时,SQL Server 将读取该设置并使用提供的值作为 backlog 设置。

要确定您是否遇到了此问题,您可以在客户端或运行 SQL Server 的计算机上运行一次“网络监视器”跟踪,看是否有直接被用一个 ACK+RESET 拒绝的套接字连接请求。如果您在“网络监视器”中检查 TCP/IP 数据包,当出现此问题时您将看到一个如下所示的数据包:

Frame: Base frame properties
ETHERNET: EType = Internet IP (IPv4)
IP: Protocol = TCP - Transmission Control; Packet ID = 40530; Total IP Length = 40; Options = No Options
TCP: Control Bits: .A.R.., len: 0, seq: 0-0, ack:3409265780, win: 0, src: 1433 dst: 4364
TCP: Source Port = 0x0599
TCP: Destination Port = 0x110C
TCP: Sequence Number = 0 (0x0)
TCP: Acknowledgement Number = 3409265780 (0xCB354474)
TCP: Data Offset = 20 bytes
TCP: Flags = 0x14 : .A.R..
TCP: ..0..... = No urgent data
TCP: ...1.... = Acknowledgement field significant
TCP: ....0... = No Push function
TCP: .....1.. = Reset the connection
TCP: ......0. = No Synchronize
TCP: .......0 = Not the end of the data
TCP: Window = 0 (0x0)
TCP: Checksum = 0xF1E7
TCP: Urgent Pointer = 0 (0x0)

注意,源端口为 0x599 或十进制的 1433。这意味着数据包来自一个典型的运行 SQL Server 而且在默认端口 1433 上运行的计算机。另外还要注意,Acknowledgement field significant 和 Reset the connection 标志已设置。如果您熟悉“网络监视器”跟踪的筛选,您可以用十六进制值 0x14 来筛选 TCP 标志值,以只查看“网络监视器”跟踪中的 ACK+RESET 数据包。

注意,如果运行 SQL Server 的计算机根本未运行,或者运行 SQL Server 的计算机未在侦听 TCP/IP 协议,您也会看到类似的 ACK+RESET 数据包,所以,仅凭看到 ACK+RESET 数据包并不能断定您遇到了此问题。如果 WinsockListenBacklog 太低,有些连接尝试会收到表示请求被接受的数据包,而有些连接在同一时间帧内会立即收到 ACK+RESET 数据包。

注意,在极少数的情况下,即使在客户端计算机上启用了连接池,您也可能必须调整此设置。例如,如果许多客户端计算机正与单个运行 SQL Server 的计算机对话,即使启用了连接池,在任何时间都可能会出现大量的并发传入连接尝试。

注意:如果您调整 WinsockListenBacklog 设置,不必重新启动 Windows 即可使此设置生效。只要停止 SQL Server 服务并重新启动它即可使此设置生效。WinsockListenBacklog 注册表设置仅适用于运行 SQL Server 的计算机。它不会对任何与 SQL Server 对话的客户端计算机产生任何影响。

更多信息

需要更多帮助?

需要更多选项?

了解订阅权益、浏览培训课程、了解如何保护设备等。

社区可帮助你提出和回答问题、提供反馈,并听取经验丰富专家的意见。

此信息是否有帮助?

你对语言质量的满意程度如何?
哪些因素影响了你的体验?
按“提交”即表示你的反馈将用于改进 Microsoft 产品和服务。 你的 IT 管理员将能够收集此数据。 隐私声明。

谢谢您的反馈!

×