WCF Net.Msmq 服务偶尔会出错

WCF Net.Msmq Service occasionally faults

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

该服务每隔几周就会停止处理消息。 windows 服务保持 运行 但 WCF 服务主机本身停止。服务主机出现以下异常故障:

Timestamp: 3/21/2015 5:37:06 PM Message: HandlingInstanceID: a26ffd8b-d3b4-4b89-9055-4c376d586268 An exception of type 'System.ServiceModel.MsmqException' occurred and was caught. --------------------------------------------------------------------------------- 03/21/2015 13:37:06 Type : System.ServiceModel.MsmqException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Message : An error occurred while receiving a message from the queue: The transaction's operation sequence is incorrect. (-1072824239, 0xc00e0051). Ensure that MSMQ is installed and running. Make sure the queue is available to receive from. Source : System.ServiceModel Help link : ErrorCode : -1072824239 Data : System.Collections.ListDictionaryInternal TargetSite : Boolean TryReceive(System.TimeSpan, System.ServiceModel.Channels.Message ByRef) dynatrace_invocationCount : 0 Stack Trace : at System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(TimeSpan timeout, Message& message) at System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(TimeSpan timeout, RequestContext& requestContext) at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(TimeSpan timeout, RequestContext& requestContext)

搜索特定异常 ("The transaction's operation sequence is incorrect") 不会产生很多信息。大多数关于如何修复故障服务的建议是在故障事件中重新启动服务主机。

我可以做到,但我希望这个异常有一个已知的可修复原因 and/or 是否有更简洁的方法来处理它。

我们在生产环境中遇到了同样的问题。不幸的是,关于它有一个 issue opened with Microsoft,但自 2013 年以来它被标记为 "Closed as Deferred"。EasySR20 提到了以下解决方法:

If you set the service's receiveTimeout a few seconds less than the service's transactionTimeout this will prevent the exception from happening and taking down the service host. These are both settings that can be set in the server's app.config file.

我还没有确认这能解决问题,但这是一种选择。

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

我们在我们的产品中遇到了这个问题,我们向微软提出了一个问题,最后他们承认它是 .NET Framework 中的一个错误,很快就会修复。

此问题已在 windows 服务器 2008 和 2012 上报告,但从未在 2016 或 windows 10 上报告过。

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

恢复服务的代码如下:

首先为主机添加一个事件处理程序来处理 "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 minutes) >=
DefaultTimeOut(15 minutes) >= WCF service 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/