我有一个自托管的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。
我可以这样做,但我希望这个例外有一个已知的可修复原因和/或是否有更清洁的方法来处理它。
答案 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>