将 MSMQ 端到端跟踪与 WCF 跟踪和应用程序级日志记录相关联
Posted
技术标签:
【中文标题】将 MSMQ 端到端跟踪与 WCF 跟踪和应用程序级日志记录相关联【英文标题】:Correlate MSMQ End-to-End trace with WCF Trace and application level logging 【发布时间】:2013-04-08 04:14:28 【问题描述】:背景:
我正在解决一个问题,即 WCF 通过事务性 MSMQ(使用 netMsmqBinding)发送的消息似乎消失了。使用 WCF 的代码位于我无法更改的第三方程序集中。我几乎没有关于问题所在的线索,但计划启用各种跟踪功能以查明问题所在。
上下文:
我已启用 MSMQ End-to-End Tracing。它为每条发送的消息记录两个事件。
将消息写入传出队列时的一个事件。此消息包含 MSMQ 消息 ID(由 guid 和整数组成,即 7B476ADF-DEFD-49F2-AF5A-0CF27C5152C0\6481271)。 该消息通过网络发送时的另一个事件。我已启用详细WCF Tracing。
我还有应用程序级日志记录,它记录由应用程序代码定义的消息 ID(我们称之为“应用程序消息 ID”)。
我已对发送的 MSMQ 消息启用正负源日志记录。
我已在接收队列上启用日志记录。
问题:
当消息丢失时,我知道丢失消息的应用程序 ID(它由发送方记录)。我现在想查看端到端跟踪以查看 消息是否写入传出队列。
如何将端到端跟踪中的事件与应用程序级别日志和 WCF 跟踪相关联?
想法:
使用 System.Messaging 中的托管 MSMQ API 发送 MSMQ 消息时,消息的 MSMQ id 在消息发送后可用。但是,当 WCF 执行发送操作时,我还没有找到记录此内容的方法。 WCF 跟踪记录了一个 MSMQMessageId guid,但令人惊讶的是,这个值并不是我猜想的实际 MSMQ id。 是否可以访问实际的 MSMQ 消息 ID 并记录它?
在应用程序日志中记录本机线程 ID 以及应用程序级别 ID 和时间戳。本机线程 ID 由 MSMQ 记录到端到端跟踪,因此这实际上可能足以关联。如果我找不到更优雅的解决方案,这对我来说是 B 计划。
【问题讨论】:
你检查Dead-Letter队列了吗? 是的,我做到了。它是空的。 我喜欢使用 perfmon 来帮助跟踪消息的生命周期。队列计数器、系统计数器等。应该能够看到各种传出队列和目标队列随着消息流经它们而上升和下降。有多少消息丢失了? 偶尔会“丢失”一些消息。您是否能够通过 perfmon 弄清楚特定消息发生了什么? 【参考方案1】:你听起来好像是在正确的轨道上。但是你可以用这个来提高一点:
使用 SvcConfigEditor.exe
-
为传播活动和活动跟踪配置 WCF 详细跟踪
为“格式错误的消息、服务消息、传输消息”配置 WCF 消息记录
使用 LogEntireMessage
端到端,全程追踪
确保在您的和第 3 方可执行文件的双方都启用这些 *.config。
收集您的日志文件,并将它们全部添加到 SvcTraceViewer.exe
【讨论】:
【参考方案2】:您可以配置 Windows MSMQ 以感知消息的主题,如果主题包含关键字则触发应用程序。此应用程序可以记录传入的消息。在发件人方面,您可以将实际消息 ID 写入消息主题并将关键字添加到主题。在接收方触发的应用程序中,可以访问主题中添加的关键字附近的实际消息 ID。
【讨论】:
【参考方案3】:WCF 似乎丢弃了您的消息,因为它在某些方面存在格式错误(即合同不匹配,超出了 WCF 消息大小限制之一)。
要捕获此错误,您可以编写一个 ErrorHanlder 来审核这些错误。 这是一个link 的示例。
如果您使用的是 Win 2008 R2 及更高版本,另一个选项是使用内置的有害消息处理。这是文档的link。
问题,使用应用程序跟踪标识符进行端到端跟踪: 我会在消息头 (look here for an example) 中传递应用程序跟踪 ID。
要在服务端审核消息头,我会使用 WCF 的 IOperationInvoker
拦截每个调用,并审核消息头中的 id。
这可以在进程的配置文件中配置,而无需更改第三方代码。here`s 一个如何实现调用程序以及如何在配置中设置它的示例。
【讨论】:
以上是关于将 MSMQ 端到端跟踪与 WCF 跟踪和应用程序级日志记录相关联的主要内容,如果未能解决你的问题,请参考以下文章
SQL调优指南笔记23:Performing Application Tracing