3

我正在尝试追踪我的应用程序无法连接到数据库服务器的可能原因。

我有一个 Windows 服务,它在启动时连接到数据库。该服务在具有可靠有线网络连接的机器上运行。它与启动自动一起安装,因此通常它在 Windows 启动时启动,并且在几乎所有情况下都可以正常工作。

但是,对于一组 XP 机器(我无法控制),当服务在 windows 启动时启动时,数据库连接失败。引发了标准异常:

System.Data.SqlClient.SqlException:建立与服务器的连接时发生错误。连接到 SQL Server 2005 时,此故障可能是由于在默认设置下 SQL Server 不允许远程连接造成的。(提供者:SQL 网络接口,错误:26 - 错误定位服务器/指定的实例)

在这些机器上,如果用户登录并手动启动服务,它会正确连接到数据库,这很奇怪。所以我猜windows启动时的问题是:

  • 服务在网络连接之前启动
  • 该服务在机器可以连接到 DNS 以解析服务器名称之前启动(如果这是解析 db 服务器名称的方式)
  • 机器上有一个策略/防火墙/等,最初阻止传出连接
  • 别的东西……

当用户手动启动服务时不会出现问题,所以一定是发生了一些事情来解决问题。我猜这要么是一个在启动时运行但在我的服务启动时尚未完成的进程,要么是用户已经登录的事实——可能是他们的登录脚本中的某些内容。

我没有直接访问机器的权限,因此需要想出问题可能是什么以及确定是否正确的方法。我不能重复部署诊断程序,所以第一次需要彻底。

所以第一个问题是:是否有人知道可能导致这种情况的桌面策略、网络策略或软件?第二个问题:我能做些什么来准确诊断正在发生的事情?

我正在考虑创建一个新的诊断服务,该服务也将安装为自动启动,并将执行各种操作以查看发生了什么,并记录此信息。例如:

  • 运行“ipconfig /all”(查看是否有网络连接)
  • 通过 IP 地址 ping 数据库服务器(查看是否可以找到服务器)
  • 按名称 ping 数据库服务器
  • 检查包含服务器名称的 HKLM 注册表项(以防以后更新 HKLM 注册表)
  • 创建与数据库的 sql 连接(以了解何时开始工作)
  • 每隔几秒钟重复这些步骤。

我将安装此服务,重新启动机器,然后在一段时间后让用户登录。诊断应该显示一些有用的信息......但有人有更好的想法或其他建议吗?

我还尝试将服务更改为具有适当权限的用户帐户运行,但这并没有解决问题。请注意,本地系统帐户确实有足够的权限来连接到数据库服务器,因为手动启动时该服务工作正常。所以这和这个问题不一样。

更新:麻烦的机器正在运行 Win XP。

更新:这篇文章很好地讨论了错误代码 26

4

3 回答 3

3

这些机器上是否有可能安装了某种防火墙,但在您的服务启动时尚未启动?我遇到过一些情况,软件防火墙将完全锁定互联网连接,直到服务完全启动并且它可以正确监控流量 - 如果是这种情况,并且您的服务启动速度比防火墙快,您可以看到什么在您的应用程序看来,它是一个断开连接的网络。

于 2009-03-26T21:04:13.433 回答
2

几个提示:

  1. 也许您应该设置从您的服务到另一个 Windows 服务(如 SQL Server 或 DTC)的依赖关系,这将确保这些服务在您的服务启动之前启动。

  2. 另一种选择(取决于您正在运行的操作系统)是延迟自动启动服务,请查看http://msdn.microsoft.com/en-us/magazine/cc164252.aspx

  3. 第三种选择:只需在服务线程第一次连接到数据库之前将一些 Thread.Sleep (或轮询循环)放入您的服务线程。

于 2009-03-26T20:50:00.953 回答
2

我们以前也遇到过这个问题。我们解决问题的方法是让启动线程在与数据库建立连接之前不会退出。我们会经常尝试连接并记录我们无法连接的事实。一旦我们建立了连接,我们将继续服务。

换句话说,让你的服务正常启动,但不要让它尝试执行任何工作,直到它知道它是否可以连接到数据库。如果您决定记录每个连接失败,请务必小心,因为您可能会用无用的日志条目填满机器。我们将记录第一次连接失败,除非重新启动服务,否则不会再次记录。

当然,如果您的数据库始终对您的服务来说是本地的,那么更好的解决方案是创建对数据库 windows 服务的依赖关系,但听起来您的数据库并不是本地的。

于 2009-03-28T16:47:47.697 回答