SQL在负载测试中拒绝连接

Posted

技术标签:

【中文标题】SQL在负载测试中拒绝连接【英文标题】:SQL refusing connection in load test 【发布时间】:2017-01-05 14:41:09 【问题描述】:

我正在我的系统上运行负载测试。在负载达到一定水平时,我的日志中开始出现 SQL 错误:

System.Data.SqlClient.SqlException (0x80131904):建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供者:Named Pipes Prprovidererror: 40 - could not operrorconnection to SQL Server)---> System.ComponentModel.Win32Exception (0x80004005): The network path was not found

通过在有问题的 SQL 服务器上运行性能监视器,我发现了以下内容:

CPU 级别很少超过 50%。 (在之前的迭代中,我看到它达到了 100% 的最大值,因此我增加了 VM 的规格,这有助于将问题推到更高的负载水平。) 用户连接数超过 8,000。 Sql Server 的默认设置为最大连接数 32,767。 连接字符串指定每个数据库的最大池大小为 1000 个连接,服务器上有 100 个数据库。负载测试在 100 个数据库之间随机分布,因此应该有一个相当均匀的分布,这意味着每个数据库大约有 80 个连接。远未达到 1k 的上限。

还有哪些其他因素可能导致 Sql Server 无法接受连接?

更新: 额外信息:我正在使用 Entity Framework Core (EF7) 进行数据库连接,如果有帮助的话。

【问题讨论】:

网络设置?您是否在 Sql Server 网络设置上验证 TCP/IP 已启用并且 IP 也已启用? technet.microsoft.com/en-us/library/hh231672(v=sql.110).aspx @NicoRiff 该问题仅在高负载时出现。否则它会起作用,因此它不能是网络设置,除非网络设置有某种限制设置。 @ShaulBehr,SQL Server 错误日志中有任何相关错误吗?多少台客户端机器?数据库服务器上的任何单个 CPU 内核是否始终显示出比其他内核高得多的利用率? @DanGuzman SQL 错误日志中没有任何内容。 42 台客户端机器。如何了解各个 CPU 内核? 哦,NM,显然,使用资源监视器......好吧,我想我必须重新运行我的测试才能找到答案。如果几个 CPU 过载,这意味着什么? 【参考方案1】:

“找不到网络路径”似乎不是与 SQL Server 容量相关的错误。作为一名前“IT 专家”,我怀疑防火墙正在丢弃您的数据包。如果这是在压力测试期间,防火墙可能会将大量请求解释为拒绝服务攻击,并使用某种预定义规则在指定时间段内断开连接。

您的网络环境是什么?如果您有具有 IPS 功能的硬件防火墙或路由器,我会检查这些日志,看看您是否发现了确凿的证据。您可能必须创建一个特殊规则以允许无限流量到您的 SQL Server。

【讨论】:

已编辑问题:我正在使用 EF Core 如果是防火墙问题,那么您使用的编码风格无关紧要。如果这是 Azure VM,我会在下次重现问题时尝试禁用其 Windows 防火墙,看看它是否再次开始工作。如果您可以访问您的物理位置之外的另一台计算机,您可以在重现问题时从该计算机尝试它,以消除您的计算机或位置上的防火墙/网络问题。如果这不能为您指明正确的方向,我会使用 WireShark 进行数据包捕获。查看端口 1433 上的流量,看看是否收到有用的错误消息。 请注意,命名管道位于端口 445,而不是端口 1433 没有决定性的答案,但我会根据迄今为止最多的投票给你赏金 @ShaulBehr 这是你的奖金,但我保留我的答案来解决我的问题。这不是人气竞赛。【参考方案2】:

有点奇怪,您获得了这么多与数据库的连接。您应该使用连接池;即使在高负载下,连接池也应该大大减少正在使用的活动连接数。

您能否提供访问数据库的代码?你是调用dispose()方法还是关闭连接?

另外,您是否查看过数据缓存是否会减轻数据库负载? 2-5 秒的数据缓存可以大大减少数据库调用。

【讨论】:

已编辑问题:我正在使用 EF Core 你能提供连接字符串吗?安全信息可以省略。 看问题的cmets 您是否尝试将 MultipleActiveResultSets 设置为 False? 除非您需要它,否则 MARS 会改变连接池的行为方式并可能影响性能。更多细节在这里。 ***.com/questions/374444/…【参考方案3】:

您遇到了 SQL-Server 侦听端口的 TCP listen() 积压限制。发生这种情况时,Windows 平台(但不是 *nix 平台)将为进一步的传入连接发出“连接被拒绝”。

我不是 SQL-Server 人,但一定有一个参数可以增加它的侦听积压。

或者,您应该在客户端研究更好或更多的连接池。

【讨论】:

这很有趣。我猜如果发生这种情况,Windows 事件日志中应该会有某种消息。 这个“TCP监听积压时间限制”有参考吗? @ShaulBehr 我没有说“TCP 侦听积压时间限制”,但我描述的行为是众所周知的。 我在 google 上的“TCP 侦听积压限制窗口”下发现了一些点击,但首先我会进入 windows 事件日志,看看是否有任何消息与此效果 @Nick.McDermaid 特别是哪个日志?我查看了应用程序、安全性和系统,并没有发现以我收到错误的速度重复出现的错误/警告/关键条目【参考方案4】:

事实证明,问题根本不在 SQL 上。问题出在我们的 API 服务器上,其中一些 API 分离了数百个并行线程,每个线程都与数据库建立自己的连接。 API 服务器的负载太大了,它开始返回“拒绝访问”异常,甚至没有真正尝试连接到数据库。

解决方案:我们使用this answer 中显示的模式限制了被分离的线程数。

【讨论】:

以上是关于SQL在负载测试中拒绝连接的主要内容,如果未能解决你的问题,请参考以下文章

负载测试后,每个新的 mio 连接都会立即挂断

VS2010 负载测试中的 SQL 跟踪显示不相关的结果

Grails/Hibernate 数据库在负载下崩溃:无法连接(即使在池中)

从 SQL 表中查询 Visual Studio 2010 负载测试数据

Locust 负载测试脚本出错 - 连接中止。',RemoteDisconnected

如何使用 Jmeter 对多个套接字连接进行负载测试?