【问题标题】:database connection doesn't work when service starts at boot but works when it's manually started服务在启动时启动时数据库连接不起作用,但在手动启动时起作用
【发布时间】:2009-03-26 20:42:11
【问题描述】:

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

我有一个 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 连接(以了解何时开始工作)
  • 每隔几秒重复一次这些步骤。

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

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

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

更新:this article 很好地讨论了错误代码 26

【问题讨论】:

    标签: .net networking windows-services database-connection


    【解决方案1】:

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

    【讨论】:

    • 有可能 - 我会问他们的管理员
    【解决方案2】:

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

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

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

    【讨论】:

    • 谢谢。你有没有弄清楚问题的原因是什么?
    • 对我们来说,问题是我们无法保证数据库服务器在服务就绪时准备就绪。我们的数据库可能是本地的,也可能不是,但我们不在乎。如果我们不能与数据库对话,我们就知道我们的服务无法工作。所以我们就等到可以了。
    【解决方案3】:

    几个提示:

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

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

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

    【讨论】:

    • 关于#1:我可以在普通电脑(没有 SQL 或 DTC)上使用什么服务来确保网络首先可用?
    • #2:很遗憾,因为它们是 XP,所以不可能
    • #3:是的,但理想情况下我想找出问题的原因并改变它而不是我的应用程序。或者两者都改变​​。
    • 我不确定这是网络问题,但如果是,我认为您应该首先尝试使用#3 - 您可以简单地对数据库服务器执行 ping (msdn.microsoft.com/en-us/library/…)一个循环,将其记录到一个文件中+当数据库服务器响应时,退出循环。
    • 将 DNS 客户端作为依赖项。这将同时捕获 DNS 和 TCP/IP,因为 DNS 客户端依赖于 TCP/IP 服务。或者结合#1和#3,并在尝试之前等待DNS客户端作为依赖后休眠60秒。
    猜你喜欢
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    • 2014-01-02
    • 2020-11-02
    • 2016-02-05
    • 1970-01-01
    相关资源
    最近更新 更多