我有一个Windows 2008 R2服务器,托管许多后端NServiceBus endpoints . 依赖于NServiceBus.Host.exe主机(作为Windows服务安装)的所有服务都能够完美地与MSDTC交互,平均在一天内完成少量并发分布式事务 . 但是,有2个小型Web.API应用程序自我托管NServiceBus endpoints (作为发布者),在尝试处理订阅请求时不断收到以下错误:
NServiceBus.Transports.Msmq.MsmqDequeueStrategy接收消息时出错 . System.Transactions.TransactionAbortedException:事务已中止 . ---> System.Transactions.TransactionManagerCommunicationException:与底层事务管理器的通信失败 . ---> System.Runtime.InteropServices.COMException:事务管理器不可用 . (来自HRESULT的异常:0x8004D01B)System.Transactions.Ot上的System.Transactions.Oletx.IDtcProxyShimFactory.ConnectToProxy(String nodeName,Guid resourceManagerIdentifier,IntPtr managedIdentifier,Boolean&nodeNameMatches,UInt32&whereaboutsSize,CoTaskMemHandle&whereaboutsBuffer,IResourceManagerShim&resourceManagerShim)(System.Transactions.Oletx.DtcTransactionManager.Initialize( )---内部异常堆栈跟踪的末尾在System.Transactions.Oletx.OletxTransactionManager.ProxyException(收到COMException收到COMException)在System.Transactions.Oletx.DtcTransactionManager.Initialize()在System.Transactions.Oletx.DtcTransactionManager.get_ProxyShimFactory( )在System.Transactions.Oletx.OletxTransactionManager.CreateTransaction(TransactionOptions属性)在System.Transactions.TransactionStatePromoted.EnterState(InternalTransaction TX)---内部异常堆栈跟踪的末尾在System.Transactions.TransactionStateAborted.CheckForFinishedTransaction(InternalTransaction TX )在System.Transactions.Tra System.Messaging.MessageQueue.StaleSafeReceiveMessage上的System.Transactions.TransactionInterop.GetDtcTransaction(事务事务)中的System.Transactions.TransactionInterop.ConvertToOletxTransaction(事务事务)中的nsaction.Promote()(UInt32超时,Int32操作,MQPROPS属性,NativeOverlapped *重叠) System.Messaging.MessageQueue.Receive(TimeSpan超时,MessageQueueTransactionType)上的System.Messaging.MessageQueue.ReceiveCurrent(TimeSpan超时,Int32操作,CursorHandle游标,MessagePropertyFilter过滤器,MessageQueueTransaction internalTransaction,MessageQueueTransactionType transactionType)中的,ReceiveCallback receiveCallback,CursorHandle cursorHandle,IntPtr事务) transactionType)位于c:\ BuildAgent \ work \ 31f8c64a6e8a2d7c \ src \ NServiceBus.Core \ Transports \ Msmq \ MsmqDequeueStrategy.cs中的NServiceBus.Transports.Msmq.MsmqDequeueStrategy.ReceiveMessage(Func`1 receive):第313行
其他一些说明:
-
错误的ApplicationPools ' identities and the Windows Services'登录用户都是相同的 .
-
这实际上在最近重新启动之前运行良好,因为Web.API服务能够成功处理订阅请求,并且能够正常发布消息(尽管发布不会自动使用MSDTC,我们没有明确使用TransactionScope) . 自本地重新启动以来,如果订阅请求消息位于Web.API发布者的任一输入队列中,我们就会收到上述错误 .
-
我已经使用了procmon.exe和MSDTC跟踪,并且没有发现任何有趣的内容 . 典型的事件查看器日志也不提供任何信息 .
-
所有 endpoints 都运行.NET 4.5和NServiceBus 4.6
-
我们无法在任何其他环境中重新创建此项 .
Additional notes from below conversations
-
抛出异常的线程是纯NServiceBus订阅管理,其中不涉及"my"代码 . 当应用程序池按需启动w3wp.exe工作进程时,NSB会生成一个不知道应用程序的工作线程来处理订阅请求 . 它应该只能在发布者's input queue and the subscription storage, which I' m上使用MSMQ,在另一个队列旁边(即根据我的知识不涉及其他服务器) .
-
网站的"code"在重新启动后没有更改,并且应用程序池在重新启动之前停止并重新启动了几次而没有问题 .
2 回答
不是答案,但评论太久了 .
您的操作的哪个部分需要DTC?分布式事务得到在需要时自动登记,通常是在与两个不同的DTC支持的基础设施位(例如MSMQ和数据库)进行通信时 .
你说你通过DTC追踪测试了 - 你的意思是DTC Ping?您是否通过在两台机器上运行(或者如果交易中涉及两个以上的机器的所有机器)进行测试? DTC工具非常深奥,其输出可能令人困惑 .
此外,如果它在重新启动之前工作,是否可以重新启动重置防火墙设置?防火墙是导致DTC问题的常见原因 .
另外,我假设您检查并重新检查了本地计算机上的DTC设置?您确定您的MSMQ队列设置为交易吗?
From your comments:
堆栈跟踪使它看起来就是它所做的一切,但我怀疑它正在尝试出列,它也试图在多个服务器之间登记事务 . 见下文 .
是的,但我要问的是为什么特定操作需要分布式事务 . 如果所有处理程序正在执行的是从队列中读取并(例如)将输出写入控制台,则MSDTC将永远不会被登记,即使处理程序包装在事务作用域中也是如此 . 它将简单地使用本地事务从队列中读取 . 升级到分布式事务是自动的,只有在需要支持多个基础结构时才会发生 .
因此,如果您最近在将数据写入新数据库服务器的处理程序中部署了代码,则可能会遇到故障,因为您现在正在招募包含新服务器的事务,这可能是发生故障的位置 .
因此,确定分布式事务中涉及的所有服务器是第一步 . 下一步是检查所有涉及的服务器上的DTC设置 . 如果DTC设置不是't the problem, I'建议使用DTCPing测试服务器之间的通信 . NServiceBus documentation有一些使用DTCPing的好指令 .
在 生产环境 环境中为我们“修复”的是将应用程序池标识用户添加到服务器上的本地Administrators组 . 遗憾的是,我们没有时间确定安全设置所需的设置,因为这不是其他类似服务器中的必需配置 . 此外,从安全角度来看,这不是最理想的解决方案,但在我们的特定情况下,我们愿意接受它 .