如何识别Windows服务中的内部故障

时间:2017-05-25 14:44:30

标签: c# windows windows-services

我们在应用程序中使用了大量自定义Windows服务。但是,我目前正在处理的问题有一个令人生气的问题:当服务继续运行时,它就会停止运行。

服务的Main方法包含在try / catch块中,如下所示:

static void Main()
{
    IRepository rep = new Repository();
    ILogger log = LogManager.GetLogger(GetType().Name);

    TimeSpan loadWindowStart = new TimeSpan(9, 0, 0);
    TimeSpan loadWindowEnd = new TimeSpan(18, 0, 0);

    foreach (SuppressionLoad sl in rep.GetSuppressionLoads().ToList())
    {
        try
        {
            // do stuff
        }
        catch(Exception ex)
        {
            // log error
        }
    }
}

该服务还会记录其中的内容,我们可以在日志繁忙时查看日志。

然而,有时,日志会停止。数据库中其他地方的活动表明整个服务已停止工作。检查服务器上的服务,该服务仍然显示状态为"已启动"。它在这种状态下占用几乎为零的系统资源,尽管它通常是处理器密集型的。如果你试图阻止它,它只是超时尝试,据我们所知,它永远不会自行停止。必须在任务管理器中终止该过程。

在这些摊位跑步的日志中没有任何不妥之处。我们在事件查看器中也找不到任何东西。

由于它没有记录错误,我不知道这里发生了什么,或者我们可以做些什么来尝试从这里诊断故障。这是非常间歇性的 - 在进入该州之前,它通常会连续几天没有问题。我们可以做些什么来调查发生了什么?

2 个答案:

答案 0 :(得分:1)

马特;在最好的条件下很难找到诸如此类的模糊问题 - 如果您的服务碰巧使用线程(我认为它确实如此),它变得非常困难并且您不能依赖于全局尝试/捕获。

一个简单的尝试是NBug(没有关联)。它将捕获未处理的异常,并为您提供有关它们的一些信息。我不认为它会让你足够。

查找这些内容的一般方法是log,log,log。您必须能够尽可能地重新创建问题 - 您需要日志告诉您的入口点到每个方法,变量值,异常堆栈跟踪(如果命中),您在每个方法中花费的时间等等。一些非常好的工具用于记录some logging tools,所以我不打算推​​荐任何一个。您可以将您的日志记录包装在一个条件编译开关中,这样一旦找到您的问题,当您将其关闭时,您将不会遇到性能损失。

可能不是你想要的答案,但多年来唯一对我有用的东西。

SteveJ

答案 1 :(得分:1)

听起来问题可能在任何地方,并不一定与提供的代码有很大关系。

关于如何解决的建议

  1. 当服务挂起时,附上调试器并查看线程并查看每个线程的位置。您可能需要重建并运行解决方案的调试版本,以便调试器具有必要的上下文符号数据。要问的问题:

    1. 我期待在那里的所有线程都存在,或者有些线程消失或下落不明?
    2. 线程是否陷入僵局(我怀疑这是发生了什么),如果是,那么是什么资源。
  2. 打开详细的日志记录并在更多的调试日志语句中进行分析,以隔离代码流的最后位置和未实现的位置,然后继续缩小位置。考虑记录上下文数据,以便在隔离有问题的行或代码块时,您可以使用上下文来尝试理解奇怪行为发生的原因。请注意记录敏感信息(即密码,PII等)
  3. 完全赞同IInspectable的评论,您可以尝试全面转储该过程(SysInternal's Process ExplorerProcDump让您这样做,或Task Manager)。它往往是使用该工具的相关经验,但正确使用可以提供很多见解,并可能在第一次出现时找到问题。
  4. 考虑到它很少发生,并且在什么地方和哪里都是大开的,可能需要几次迭代才能触发问题以缩小范围。