6

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

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

时间戳:2015 年 3 月 21 日下午 5:37:06 消息:HandlingInstanceID:a26ffd8b-d3b4-4b89-9055-4c376d586268 发生并捕获了“System.ServiceModel.MsmqException”类型的异常。-------------------------------------------------- ------------------------------- 03/21/2015 13:37:06 类型:System.ServiceModel.MsmqException,系统.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 消息:从​​队列接收消息时出错:事务的操作顺序不正确。(-1072824239,0xc00e0051)。确保 MSMQ 已安装并正在运行。确保队列可用于接收。来源:System.ServiceModel 帮助链接:错误代码:-1072824239 数据:System.Collections.ListDictionaryInternal TargetSite:布尔 TryReceive(System.TimeSpan, System.

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

我可以这样做,但我希望有一个已知的可解决此异常的原因和/或是否有更清洁的方法来处理它。

4

2 回答 2

3

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

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

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

恢复服务的代码如下:

首先,您为主机添加一个事件处理程序来处理“故障”事件:

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

更新:经过进一步调查,在微软的帮助下,我们找到了问题的根本原因,即以下之间的超时顺序:

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/

于 2018-10-09T05:37:23.813 回答
1

我们的生产环境也有同样的问题。不幸的是,微软对此提出了一个问题,但自 2013 年以来它被标记为“已延期关闭”。EasySR20 提到了以下解决方法:

如果您将服务的 receiveTimeout 设置为比服务的 transactionTimeout 少几秒钟,这将防止异常发生并关闭服务主机。这些都是可以在服务器的 app.config 文件中设置的设置。

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

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

于 2017-05-04T14:58:07.753 回答