3

我们正在尝试为 Windows 编写服务,并且需要制定冗余计划,以便如果应用程序中的某些内容出现故障,它会再次恢复。我想知道我是否可以使用多线程来完成这个。

我的想法是创建两个线程,每个线程处理单独的任务。我还想让每个线程监视另一个线程以确保它仍在运行,如果不是,那么它应该启动该线程的新实例。这听起来可行吗?我将使用哪些线程技术:互斥体、共享内存、信号量等...?如果这不是正确的方法,那么可能是什么,只需编写两个单独的服务并使用 IPC?

4

4 回答 4

4

那么让您的服务在失败时重新启动的最简单方法是让 Windows 来做。您只需将服务配置为自动重启,这真的很容易。您也可以在服务安装程序期间以编程方式执行此操作。有关如何执行此操作的指南,请参阅这篇文章:构建 Windows 服务 - 第 4 部分:扩展服务安装程序

至于这提供“冗余”,这没有。冗余的正确定义意味着您拥有不止一个。这可能是使用多个服务,或者更有可能在多个主机上使用多个服务。在单个主机上拥有多个服务更容易,因为您可以在需要时使用互斥锁进行同步。

真正的问题是这项服务在做什么?

如果您的服务正在轮询任务,例如来自数据库或消息队列,那么同步会为您处理。只需对您的数据库进行建模,以便多个服务都可以独立运行和处理工作,而无需重复工作。现在你有了冗余。

于 2012-05-16T18:06:12.967 回答
3

是的,这听起来像是一个可行的解决方案。双线程的唯一问题是,如果应用程序崩溃,那么两个线程都会死掉(如果它们是后台线程) 我发现对这个问题有用的解决方案是有一个看门狗进程。每当工作进程崩溃时,看门狗就会启动并创建一个新实例并运行它。

于 2012-05-16T18:02:02.200 回答
2

您可以简单地将应用程序编写为 Windows 服务使用的类库(Visual Studio 中的模板,您需要添加安装程序)。如果您以这种方式运行您的应用程序,您将可以随时选择设置失败时的行为,即始终重新启动,重新启动几次,然后向某人发送电子邮件或运行其他应用程序等。

它内置在您拥有凭据的任何 Windows 框中,所有繁重的工作都为您完成。对于我需要始终启动和运行的服务来说,这始终是一件轻而易举的事。

为此,您只需将服务类型设置为自动(如果您的机器重新启动,这将重新启动它),然后您可以在管理窗口的管理窗口中为需要的前三个重新启动选项进行设置服务部分。

更多信息: Windows 服务文档

于 2012-05-16T18:07:27.650 回答
0

我发现涵盖各种情况的最强大的解决方案是有一个可以启动和停止工作进程的看门狗进程。您将使用 WCF 在进程之间来回发送信号(或其他信息)。这个想法是保持看门狗过程简单,这样它在执行有限的任务集时失败的可能性很小。然后把所有有风险的逻辑放到worker进程中。

提出一个协议,用于将工作进程的故障或健康状况传达给看门狗进程。这里有一些想法。这份清单绝不是一份详尽的清单。

  • 如果看门狗没有及时收到状态报告,它会重新启动工作进程。
  • 如果 Watchdog 收到失败状态报告,它会重新启动工作进程。
  • 如果检测到内存泄漏,Watchdog 会重新启动工作进程。
  • 如果看门狗没有运行,它会启动工作进程。

除了最后一项,Windows 服务控制管理器无法处理其他 3 种情况。这也是我喜欢看门狗进程理念的原因之一。另一个原因是因为您的主要逻辑可能会挂断阻塞调用。因为Thread.Abort不推荐,因为它会破坏状态,所以除了杀死工作进程之外,你真的只有很少的选择。

此外,请尝试使您的主要逻辑尽可能容错。这样,如果您确实需要强制终止它,那么恢复和清理它留下的混乱会容易得多。这可能意味着使用诸如 DB 事务或聪明的文件操作之类的原子操作。

于 2012-05-16T19:37:20.093 回答