【问题标题】:MSDTC fails for self-hosted NServiceBus ASP.NET endpoints but not other processes对于自托管的 NServiceBus ASP.NET 端点,MSDTC 失败,但其他进程则失败
【发布时间】:2015-09-23 17:19:29
【问题描述】:

我有一个托管许多后端 NServiceBus 端点的 Windows 2008 R2 服务器。所有依赖于 NServiceBus.Host.exe 主机(作为 Windows 服务安装)的服务都能够与 MSDTC 完美交互,全天平均处理少量并发分布式事务。然而,有 2 个小型 Web.API 应用程序自托管 NServiceBus 端点(作为发布者)在尝试处理订阅请求时不断收到以下错误:

NServiceBus.Transports.Msmq.MsmqDequeueStrategy 接收错误 消息。 System.Transactions.TransactionAbortedException: 交易已中止。 ---> System.Transactions.TransactionManagerCommunicationException: 与底层事务管理器的通信失败。 ---> System.Runtime.InteropServices.COMException:事务管理器 不可用。 (来自 HRESULT 的异常:0x8004D01B)在 System.Transactions.Oletx.IDtcProxyShimFactory.ConnectToProxy(字符串 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) --- 内部异常堆栈跟踪结束 --- at System.Transactions.TransactionStateAborted.CheckForFinishedTransaction(InternalTransaction tx) 在 System.Transactions.Transaction.Promote() 在 System.Transactions.TransactionInterop.ConvertToOletxTransaction(交易 交易)在 System.Transactions.TransactionInterop.GetDtcTransaction(交易 交易)在 System.Messaging.MessageQueue.StaleSafeReceiveMessage(UInt32 超时, Int32 动作、MQPROPS 属性、NativeOverlapped* 重叠、 ReceiveCallback receiveCallback, CursorHandle cursorHandle, IntPtr 交易)在 System.Messaging.MessageQueue.ReceiveCurrent(时间跨度超时,Int32 动作,CursorHandle 游标,MessagePropertyFilter 过滤器, MessageQueueTransaction 内部事务, MessageQueueTransactionType 事务类型)在 System.Messaging.MessageQueue.Receive(时间跨度超时, MessageQueueTransactionType 事务类型)在 NServiceBus.Transports.Msmq.MsmqDequeueStrategy.ReceiveMessage(Func`1 接收)在 c:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\Transports\Msmq\MsmqDequeueStrategy.cs:line 313

其他一些注意事项:

  • 错误的 ApplicationPools 的身份和 Windows 服务的登录用户是相同的。
  • 这在之前确实运行良好 最近重新启动,因为 Web.API 服务能够成功 处理订阅请求,并且能够发布消息 很好(虽然发布不会自动使用 MSDTC,而且我们是 不明确使用 TransactionScope)。由于本地重启,我们 如果有订阅请求消息,则只需获取上述错误 在任一 Web.API 发布者的输入队列中。
  • 我使用了 procmon.exe 和 MSDTC 跟踪,但没有发现任何感兴趣的东西。典型的事件查看器日志也不提供任何信息。
  • 所有端点都运行 .NET 4.5 和 NServiceBus 4.6
  • 我们不能 在任何其他环境中重新创建它。

以下对话的补充说明

  • 抛出异常的线程是纯 NServiceBus 订阅管理,其中不涉及任何“我的”代码。当应用程序池按需启动 w3wp.exe 工作进程时,NSB 会生成一个应用程序不知道的工作线程来处理订阅请求。它应该只在发布者的输入队列和订阅存储中工作,我也在使用 MSMQ,在另一个队列旁边(即据我所知,不涉及其他服务器)。
  • 网站的“代码”在重新启动后没有改变,并且应用程序池在重新启动前停止并重新启动了几次,没有问题。

【问题讨论】:

  • 这对您来说仍然是个问题吗?我遇到了同样的问题,因为(据说)神奇地我们的 DTC 不再有网络访问权限。我知道这个问题已经超过 3 个月了,但我很想知道解决方案是什么。我的问题通过以下方式解决:technet.microsoft.com/en-us/library/Cc753510(v=WS.10).aspx

标签: asp.net .net transactions nservicebus msdtc


【解决方案1】:

不是真正的答案,但评论太长了。

您的哪些操作部分需要 DTC?分布式事务会在需要时自动登记,通常是在您与两个不同的支持 DTC 的基础设施位(例如 MSMQ 和数据库)通信时。

您说您通过 DTC 跟踪进行了测试——您的意思是 DTC Ping?您是否通过让它在两台机器上运行(如果事务中涉及多于两台,则在所有机器上运行)进行测试? DTC 工具非常深奥,它的输出可能令人困惑。

另外,如果它在重新启动之前确实有效,是否可以重新启动重置防火墙设置?防火墙是 DTC 问题的常见原因。

另外,我假设您检查并重新检查了本地计算机上的 DTC 设置?您是否确保将您的 MSMQ 队列设置为事务性的?

来自您的 cmets:

请注意,当尝试使 来自本地私有 MSMQ 队列的消息 [...]

堆栈跟踪看起来就是它所做的一切,但我怀疑它在尝试出队时也在尝试征用多个服务器之间的事务。见下文。

为什么选择 MSDTC?这是支持精确一次消息传递的原始方式 NServiceBus(见此处)。

是的,但我要问的是为什么特定操作需要分布式事务。如果处理程序所做的只是从队列中读取并(例如)将输出写入控制台,则 MSDTC 将永远不会被征用,即使处理程序被包装在事务范围内。它将简单地使用本地事务从队列中读取。升级到分布式事务是自动的,并且仅在需要支持多个基础架构时才会发生。

因此,如果您最近在将数据写入新数据库服务器的处理程序中部署了代码,您可能会遇到故障,因为您现在正在征用包括新服务器的事务,而这可能是发生故障的地方。

因此,第一步是确定分布式事务中涉及的所有服务器。下一步是检查所有相关服务器上的 DTC 设置。如果 DTC 设置不是问题,我建议使用 DTCPing 测试服务器之间的通信。 NServiceBus documentation 有一些关于使用 DTCPing 的很好的说明。

【讨论】:

  • 为什么选择 MSDTC? 这是在 NServiceBus 中支持一次性消息传递的原始方式(请参阅 here)。这就是我所说的DTC TracingMSDTC 设置:双重和三重检查。
  • DTCPing:我没有在这台服务器上使用它,因为 MSDTC 对所有其他进程都运行良好。请注意,当尝试从 本地 私有 MSMQ 队列中取出消息时会发生此特定故障,所有其他服务都在分布式事务中无缝执行该队列。同样,所有其他服务都以同一个用户身份运行,只是不在 IIS 的上下文中。
  • 重启时防火墙设置是否发生了变化? 这是一个有趣的问题,因为它有可能发生。我将对此进行深入研究,但是除了已经提到的内容之外,是否有一些低级别的跟踪/日志记录/调试可以用来确定这是否是一个问题?我认为 procmon.exe 会捕获 tcp/ip 连接问题,但我没有看到任何这些问题。
  • 更新:此服务器的 Windows 防火墙已关闭。
  • 根据您的 cmets 添加到我的答案中。
【解决方案2】:

在生产环境中为我们“解决”的问题是将应用程序池身份用户添加到服务器上的本地管理员组。不幸的是,我们没有时间确定安全设置需要什么设置,因为在其他类似服务器中这不是必需的配置。此外,从安全角度来看,这不是最理想的解决方案,但在我们的特定情况下,我们愿意接受它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 2013-12-28
    • 2023-02-10
    • 1970-01-01
    相关资源
    最近更新 更多