繁体   English   中英

MSMQ + WCF-立即将邮件移到按字母顺序排列的队列中

[英]MSMQ + WCF - Immediately Move Messages to the Dead-Letter Queue

我们有一个WCF服务,用于侦听队列(MSMQ)上的消息。 它将请求发送到我们的Web服务器(REST API),该服务器返回HTTP状态代码。

如果状态代码在400范围内,则我们将丢弃该消息。 这个想法是400范围的错误永远不会成功(未经授权,错误的请求,未找到等),因此我们不希望继续重试。

对于所有其他错误(例如500-内部服务器错误),我们将WCF配置为将消息放入“重试”队列。 经过一定时间后,重试队列上的消息将被重试。 想法是服务器暂时关闭,因此请重试。

WCF的设置方式,如果我们在服务协定中抛出FaultException ,它将自动将消息放入重试队列。

当消息导致400范围错误时,我们只是吞下了该错误(我们只是记录了该错误)。 这样可以防止重试机制触发。 但是,最好将消息移到死信队列中。 这样,我们可以通过向用户和/或系统管理员发送电子邮件来对错误做出反应。

有没有一种方法可以立即将这些不良消息移动到死信队列中?

首先,我一直提到死信队列。 当我发布此问题时,我还没有意识到WCF / MSMQ会自动创建所谓的有毒子队列。 任何无法在配置的次数内传递的消息都将放入毒物子队列中。

在我的情况下,我知道某些消息永远不会成功,因此我想立即将消息移出队列。

解决方案是创建第二个队列,我称之为“毒药”(不要与毒药子队列相混淆)。 我的catch块将创建WCF客户端的实例,并将消息转发到该中毒队列。 我可以重用同一个客户端,以同时发布到原始队列和中毒队列; 我只需要在每个配置文件中创建一个单独的客户端端点。

我有两个运行的独立ServiceHost实例正在读取队列。 发生不可恢复的错误时,原始队列的ServiceHost执行HTTP请求,并将消息转发到中毒队列。 第二个ServiceHost只需发送一封电子邮件以记录一条消息丢失。

还有临时错误超出最大尝试次数的问题。 WCF / MSMQ自动创建一个名为<myqueuename>;poison的子队列。 您不能通过WCF直接写入子队列,但可以使用ServiceHost从中读取。 每当消息在有毒子队列中结束时,我都将消息转发到有毒剂队列,并使用与原始处理程序的catch块中使用的客户端完全相同的客户端。

我希望能够在错误电子邮件中包含堆栈跟踪。 由于我为所有处理程序重用了相同的客户端和服务协定,因此我不能只是将堆栈跟踪作为字符串传递(除非我将其添加到所有数据协定中)。 取而代之的是,我让中毒处理程序尝试再次执行代码,这将再次失败并吐出堆栈跟踪。

这就是我的消息队列的最终样子:

MyQueue
    - Queue messages
    - Retry
    - Poison
MyQueuePoison
    - Queue messages

这种方法非常复杂。 从WCF服务处理程序中调用WCF客户端很奇怪。 这还意味着在服务器上再设置一个队列,并设置大量其他配置节来指定客户端应将消息转发到哪个队列。

希望我已经理解了您的问题,如果这是我认为您在说的话,那么是的,但是显然您需要对此进行编程。 但是您确实需要设置重试数量,以便MSMQ可以重试直到放弃。 或者,您可以为死信/消息创建自己的自定义队列

http://msdn.microsoft.com/en-us/library/ms789035(v=vs.110).aspx http://msdn.microsoft.com/en-us/library/ms752268(v=vs.110)的.aspx

在这里也看看:

http://www.michaelfcollins3.me/blog/2012/09/20/wcf-msmq-bad-message-handling.html

如何处理WCF的MSMQ绑定中的消息失败

希望这些链接对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM