• 当 SQL Server 连接池被禁用时您可能必须调整的 TCP/IP 设置的描述


    当 SQL Server 连接池被禁用时您可能必须调整的 TCP/IP 设置的描述

    概要

    在使用 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 (http://support.microsoft.com/kb/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 (http://support.microsoft.com/kb/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 对话的客户端计算机产生任何影响。
     
     
     
    案例:https://bbs.csdn.net/topics/391846569
  • 相关阅读:
    面试必备的数据库悲观锁与乐观锁
    5分钟带你读懂事务隔离性与隔离级别
    带你了解数据库中事务的ACID特性
    带你了解数据库中group by的用法
    带你了解数据库中JOIN的用法
    一篇带你读懂TCP之“滑动窗口”协议
    通过“表白”的方式,让我们快速了解网络协议
    聊一聊Iterable与Iterator的那些事!
    一篇让你明白进程与线程之间的区别与联系
    MySQL 索引的增删查
  • 原文地址:https://www.cnblogs.com/proxyz/p/8601315.html
Copyright © 2020-2023  润新知