连接超时已过期但没有明显的网络问题

Mit*_*tch 6 sql-server vmware connectivity sql-server-2016

我们有一个特定的 SQL Server,它在接受连接时会间歇性地超时。该问题全天都是一致的,但发生率非常低。如何继续排除故障?

连接超时已过期。尝试使用登录前握手确认时超时时间已过。这可能是因为登录前握手失败或服务器无法及时响应。尝试连接到此服务器所花费的持续时间是 - [Pre-Login] 初始化 = 0; 握手=15002;(Microsoft SQL Server,错误:-2)

服务器配置:

  • SQL Server 2016 SP1 CU5 Enterprise(SP1 之前也出现过问题)
  • 服务器和客户端上的 Windows Server 2012 R2
  • HP ProLiant DL360 Gen9 上的 VMware ESXi,6.5.0
  • VM 有 8 个 vCPU,64 GiB 内存(完全保留)

测试脚本(每秒执行一次):

$failed = $false;
$loginDuration = (Measure-Command {
    $ncon = New-Object System.Data.SqlClient.SqlConnection `
        @( 'Data Source=1.2.3.4,16143;Database=Test;User=Test;Password=****;Pooling=false;' );
    try 
    {
        $ncon.Open();

        $cmd = New-Object System.Data.SqlClient.SqlCommand `
            @( 'SELECT @@VERSION', $ncon );
        $cmd.ExecuteNonQuery();

        $ncon.Dispose();
    }
    catch
    {
        $failed = $true;
    }
}).TotalMilliseconds;
Write-Metric -metric 'itp.dbserver.logintime' -unit 'milliseconds' `
    -value (&{if ($failed) { 120000 } else { $loginDuration }});
Run Code Online (Sandbox Code Playgroud)

观察:

  • 在操作系统更新、SQL Server 更新、San 移动以及从 Hyper-V 移动到 VMWare 后开始出现问题
  • 大多数连接成功(1,440 次尝试中有 4 次失败)
  • 在“[Pre-Login] 初始化=0;”中,失败总是以较低的数字列出 并且“握手= 15002”中的数字很高。我们不会收到诸如“未找到”或“不知道此类主机”之类的错误,只有“连接超时”
  • 没有为侦听器启用加密
  • Ping 显示在长时间内没有丢失(发送的 96,045 个中丢失了 0 个)
  • 所有防火墙都被禁用
  • 尝试使用 IPv6 和 IPv4 地址的连接以相同的速率失败
  • CPU 低级 (<40%)
  • 活动会话持续在 400 左右
  • 气球驱动程序被禁用
  • 一旦建立连接是稳定的,执行查询时没有意外错误,没有奇怪的断开连接。
  • 多个客户端在连接时遇到问题 - 来自多台计算机的 ODBC 和 ADO

更新:我终于得到了连接失败的客户端 Wireshark 跟踪。没有明显的数据包丢失,客户端实时接收 TCP ACK(<10 毫秒)。客户端在失败时正在使用 DNS 名称,但使用连接字符串中的 IPv4 地址确实发生了故障。

Wireshark 对话图显示服务器未响应超过 15 秒

我是否正确地认为,我立即收到发送的登录前请求数据包的 TCP ACK 会将问题本地化到操作系统或 SQL Server?