【问题标题】:SQLConnection use randomly namedpipes instead of tcpSQLConnection 使用随机命名管道而不是 tcp
【发布时间】:2016-09-23 13:47:32
【问题描述】:

SQLConnection 使用随机命名的管道(445)而不是 tcp(1433)。 namedpipes 端口被我们的防火墙阻止,但不是 tcp。这只发生在尝试连接到我们的一个 sql 服务器时。大多数情况下,应用程序使用 tcp,但随机尝试使用 namedpipes 端口。我们的 sql 连接非常简单,我们不会用它做任何花哨的事情。

我们不想在我们的连接字符串上硬编码 tcp 端口。我们已经尝试过了,它解决了问题。该问题仅在上周出现,我们尝试连接的 Web 应用程序运行了一段时间。

为什么 sql 连接有时会尝试连接 445 而不是 1433?这是 .net 最新更新引入的错误,还是服务器可以指定下一个要使用的端口?

更新 2016-09-23 11:00

这是我们用来连接的代码示例

string connectionString = "Data Source=SERVERNAME;Initial Catalog=DATABASE;uid=username;pwd=mypass;MultipleActiveResultSets=True";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    try {
        connection.Open(); 
…

【问题讨论】:

  • 你能贴出你的连接字符串代码吗
  • 您永远不会提到此连接是否来自最终用户 PC、Web 服务器、其他数据库服务器等。但是,无论是使用命名管道还是 TCP 是本地 PC 上发起的连接设置连接。有关更多详细信息,请参阅msdn.microsoft.com/en-us/library/ms181035.aspx。
  • 要么是web服务器,要么是客户端pc连接到sql server。
  • 没有错误,这是您的连接字符串所要求的。 SERVERNAME 不是 FQDN,因此不能被视为 TCP 服务器名称。 SQL Server 必须检查每个可用的协议以确定哪个协议可以实际连接。如果启用了命名管道,将首先尝试。
  • @AntonKrouglov,应用程序尝试命名管道的原因仅仅是因为 TCP 连接失败。客户端驱动程序捕获 TCP 连接失败,然后尝试使用命名管道作为后备,混淆原始 TCP 错误。

标签: c# .net sql-server sqlconnection


【解决方案1】:

我们不想在连接字符串上硬编码 tcp 端口。

您不必将 IP 地址/端口号放在连接字符串中。

但是,你可以在连接字符串中强制网络协议。

Network Library=DBMSSOCN;

https://www.connectionstrings.com/define-sql-server-network-protocol/

但是当我遇到随机命名管道问题导致性能下降时,我会尽可能将连接字符串设置为“特定”。即...指定网络库以及 ip 地址和端口号。

顺便说一句,我真的很希望你实际上并没有在编译代码中编码你的连接字符串,下面不是你的实际代码。

string connectionString = "Data Source=SERVERNAME;Initial Catalog=DATABASE;uid=username;pwd=mypass;MultipleActiveResultSets=True";

追加:

您可以在问题机器上围绕这个注册表设置“钓鱼”。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\

我会特别查看是否设置了 DSQUERY。

https://support.microsoft.com/en-us/kb/328306

检查以下注册表子项中指定的协议: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\DSQUERY 此值通常反映 CNU 中的设置,但有时 它不是。

如果值为 DBNETLIB,则它使用以下协议之一 CNU的启用协议列表。如果一个特定的协议是 列出,则使用该协议。

如果这是问题......最终,任何其他程序都可以更改此值。所以你没有完全的控制权。同样,更好的解决方案是将网络库放在连接字符串中,这样“外部力量”就无法在游戏中期改变你的游戏。
我知道这是因为我在客户端站点被烧毁了……其他一些程序将 DSQUERY 值更改为大约 1/3 的客户端计算机(也正在使用我们的应用程序)并且我们的应用程序性能达到爬行。 Aka,其他一些公司....做了一些事情让我们的应用程序性能变得糟糕。因此,我没有与之抗争,而是将网络库放入我们的连接字符串中以永久解决该问题。

【讨论】:

  • 我们知道这一点,我们不想指定要使用的协议,因为自从 Web 应用程序上线以来一切正常(2 年前)。为什么突然 sql 连接有这种奇怪的行为来使用 445。
  • 这只是测试代码,顺便说一句,我们没有编译我们的连接字符串。
  • 我在答案中附加了一个新建议。
  • 这是一种可靠的方法,尤其是在具有许多客户端计算机 (+1) 的企业环境中。
  • @Igor。对,DSQUERY 的内容与您的答案完全一致。只是另一个难题。也支持您的答案。
【解决方案2】:

您永远不会提到此连接是否来自最终用户 PC、Web 服务器、其他数据库服务器等。但是,是否使用命名管道或 TCP 作为主要协议是创建连接的 PC 上的设置。这可以使用SQL Server Native Client Configuration 进行配置,也可以在连接字符串中覆盖。

更改客户端计算机的默认协议或协议顺序

  1. 在 SQL Server 配置管理器中,展开 SQL Server Native Client 配置,右键单击客户端协议,然后单击属性。
  2. 在“启用的协议”框中,单击“上移”或“下移”以更改尝试连接到 SQL Server 时尝试协议的顺序。已启用协议框中的顶部协议是默认协议。

配置客户端使用 TCP/IP

  1. 在 SQL Server 配置管理器中,展开 SQL Server Native Client 配置,右键单击客户端协议,然后单击属性。
  2. 在“启用的协议”框中,单击向上和向下箭头以更改尝试连接到 SQL Server 时尝试协议的顺序。已启用协议框中的顶部协议是默认协议。

见Configure Client Protocols

【讨论】:

  • @sebascomeau - 看起来不错,但问题仍然存在,还是很好,因为它解决了问题?
  • 抱歉,问题依旧。这是好的顺序。 (我的坏)
  • SERVERNAME 不是 FQDN,因此驱动程序必须首先尝试命名管道。使用全名或指定 TCP 库
【解决方案3】:

为什么 sql 连接有时会尝试连接 445 而不是 1433?它是.net最新更新引入的错误还是服务器 可以指定下一个要使用的端口吗?

决定协议顺序的是客户端而不是服务器。大多数客户端驱动程序将首先使用 TCP/IP,然后在 TCP 连接失败时使用命名管道。以下是适用于 SqlClient 的 documentation 的相关摘录。

例如,如果客户端计算机同时具有 TCP 和命名管道 可用,顺序为:

  • TCP
  • 命名管道

当客户端计算机尝试建立 TCP 连接到服务器并且连接尝试返回非零 返回代码,客户端通过使用透明地尝试连接 列表中的下一个协议,即命名管道。在这种情况下, 客户端无法建立 TCP 连接;但是,客户端成功 建立命名管道连接。

注意

The client does not receive an error that indicates the first protocol failed.

如果客户端应用程序使用第二个协议,它也 返回错误,错误返回给客户端。

因此,为了更直接地回答您的问题,尝试命名管道只是因为初始 TCP 连接失败。客户端错误消息表明命名管道连接失败,但这只是初始 TCP 连接失败的副作用。根据您的症状,根本原因是间歇性的数据库或网络连接问题,与使用命名管道完全无关。

【讨论】:

    【解决方案4】:

    服务器端呢?

    我会仔细检查服务器上的 SQL Server 实例配置:

    • 服务器上启用了哪些协议并按预期运行
    • 在显示意外行为的服务器上启用了哪些协议

    我的猜测是,“损坏”的服务器启用了命名管道,而其他服务器没有启用,当 .NET 客户端选择连接协议时,有时会做出错误的选择。

    这是一个疯狂的猜测,因为我不知道 .NET 是如何选择连接协议的......

    【讨论】:

    • 我们检查了 sql server 配置,一切都是正确的顺序。我们的应用程序和 Web 服务器在一定时间内使用 tcp 协议,突然间使用了命名管道,我们收到了一个错误。在我们重试之后,它需要 tcp。
    • 这不包括我的建议。配置是否与“正常工作”的服务器相同?
    • 在您遇到问题的服务器上禁用命名管道怎么样?
    • 是的,我们所有的 sql 服务器都有相同的配置。没有区别。我们试图找出导致这个问题最近出现的原因,而我们知道应用程序和 sql 服务器之间没有任何变化。
    【解决方案5】:

    我遇到了这个问题。我怀疑是 AppLocker 限制或从网络驱动器上运行应用程序导致了这种情况。我在本地复制了应用程序并解决了 applocker 限制,现在它似乎使用了正确的端口。

    我没有收到任何错误,甚至使用连接字符串强制参数也无法修复它。现在它按预期使用端口 1433。

    【讨论】:

      【解决方案6】:

      您收到这些错误的原因可能有多种。检查所有步骤。

      1.检查您是否可以 ping SQL Server 框

      确保您能够从客户端计算机 ping 安装 SQL Server 的物理服务器。如果没有,您可以尝试使用 IP 地址(对于默认实例)或 IP 地址\实例名称(对于命名实例)连接到 SQL Server。

      2.检查 SQL 服务是否正在运行

      确保 SQL 服务正在运行 您可以使用 SC 命令或 SQL Server 配置管理器检查 SQL Server 服务。很多时候您可能会发现 SQL Server 实例没有运行。

      1. 检查 TCP/IP 和命名管道是否已启用

      检查 TCP/IP 和命名管道协议和端口。打开 SQL Server 配置管理器并检查 SQL Server 网络配置协议。您应该启用命名管道和 TCP/IP 协议。

      4.检查该服务器是否允许远程连接

      检查是否启用了允许此服务器的远程连接。在 SSMS 中,右键单击实例名称并选择属性。转到连接选项卡并确保选中允许远程连接到此服务器。如果需要进行更改,则必须重新启动 SQL Server 实例以应用更改。

      5.检查防火墙是否阻止访问 SQL Server

      为 SQL Server 端口和 SQL Server Browser 服务配置 Windows 防火墙。转到控制面板并单击 Windows 防火墙。转到例外选项卡,如下所示。您可以阅读此提示配置 Windows 防火墙以使用 SQL Server 了解更多信息。

      【讨论】:

      • 在我的特殊情况下,99.9% 的时间一切正常 - ping、端口探测、服务正在运行等。这只是一个不时发生的间歇性问题。命名管道在服务器上被故意禁用。
      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 2014-11-26
      • 2015-08-14
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多