WCF Net.Msmq服务偶尔会出现故障

时间:2015-03-23 21:15:01

标签: wcf msmq-wcf

我有一个自托管的WCF服务(在Windows服务中运行)。此服务侦听MSMQ上的消息。该服务是PerCall,并且在Windows 2008 R2,.NET 4.0,MSMQ 5.0上运行Transactional。

每两周一次,该服务将停止处理消息。 Windows服务仍在运行,但WCF服务主机本身停止。 servicehost出现以下异常:

  

时间戳:3/21/2015 5:37:06 PM消息:HandlingInstanceID:   a26ffd8b-d3b4-4b89-9055-4c376d586268类型例外   'System.ServiceModel.MsmqException'发生并被捕获。   -------------------------------------------------- ------------------------------- 03/21/2015 13:37:06类型:System.ServiceModel.MsmqException,   System.ServiceModel,Version = 4.0.0.0,Culture = neutral,   PublicKeyToken = b77a5c561934e089消息:发生错误   从队列接收消息:事务的操作   序列不正确。 (-1072824239,0xc00e0051)。确保MSMQ是   安装并运行。确保队列可以接收   从。来源:System.ServiceModel帮助链接:ErrorCode:   -1072824239数据:System.Collections.ListDictionaryInternal TargetSite:Boolean TryReceive(System.TimeSpan,   System.ServiceModel.Channels.Message ByRef)dynatrace_invocationCount   :0堆栈跟踪:at   System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(时间跨度   超时,消息&消息)   System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(时间跨度   超时,RequestContext& requestContext)at   System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(时间跨度   超时,RequestContext&的RequestContext)

搜索特定异常(“事务的操作顺序不正确”)不会产生大量信息。关于如何纠正故障服务的大多数建议是在故障事件中重新启动servicehost。

我可以这样做,但我希望这个例外有一个已知的可修复原因和/或是否有更清洁的方法来处理它。

2 个答案:

答案 0 :(得分:1)

我们的生产环境存在同样的问题。不幸的是,它有一个issue opened with Microsoft,但它自2013年起被标记为“已关闭为延迟”.EasySR20提到了以下解决方法:

  

如果你将服务的receiveTimeout设置为比theTime少几秒   service的transactionTimeout这将阻止异常   发生并取消服务主机。这些都是设置   可以在服务器的app.config文件中设置。

我还没有确认这可以解决这个问题,但这只是一个选择。

我们已经实现了服务故障重启选项。

答案 1 :(得分:1)

我们在产品中遇到了这个问题,我们向Microsoft开了张罚单,最终他们承认它是.NET Framework中的错误,并将很快得到修复。

该问题已在Windows Server 2008和2012上报告,但从未在2016或Windows 10上报告过。

因此,我们做了两个解决方案,建议所有客户升级到Windows 2016,并添加了一个代码来处理服务主机重启服务时出现的故障(您可以通过在启动MSMQ服务的同时重启MSMQ服务来模拟相同的错误, WCF服务主机已打开。

还原服务的代码如下:

首先,为主机添加事件处理程序以处理“ Faulted”事件:

SH.Faulted += new EventHandler(SH_Faulted);
//SH is the ServiceHost

然后在事件处理程序内

 private static void SH_Faulted(object sender, EventArgs e)
        {

        if (SH.State != CommunicationState.Opened)
        {

            int intSleep = 15 * 1000;
            //Abort the host
            SH.Abort();

            //Remove the event
            SH.Faulted -= new EventHandler(SH_Faulted); 

            //I sleep to make sure that the MSMQ have enough time to recover, better make it optional.
            System.Threading.Thread.Sleep(intSleep);
            try
            {
                ReConnectCounter++;
                LogEvent(string.Format("Service '{0}' faulted restarting service count # {1}", serviceName, ReConnectCounter));

                  //Restart the service again here
            }
            catch (Exception ex)
            {
                //failed.. .you can retry if you like
            }
        }
    }

最终错误将再次发生,但是您的服务将继续正常运行,直到Microsoft解决此问题或您升级到2016年为止

已更新: 经过进一步的调查,并在Microsoft的帮助下,我们找到了问题的根本原因,这是以下情况之间的超时顺序:

  

MachineLeveDTCTimeOut(20分钟)> =
  DefaultTimeOut(15分钟)> =   WCF服务transactionTimeout>
  receiveTimeout()

因此,通过添加以下内容可以解决此问题:

<system.transactions>
      <defaultSettings timeout="00:05:00"/>
</system.transactions>

更详细的文章: https://blogs.msdn.microsoft.com/asiatech/2013/02/18/wcfmsmq-intermittent-mq_error_transaction_sequence-error/