MSMQ + WCF - 立即将消息移动到死信队列

时间:2014-05-30 19:04:31

标签: wcf message-queue msmq netmsmqbinding wcf-4

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

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

对于所有其他错误(例如,500 - 内部服务器错误),我们将WCF配置为将消息放在“重试”队列中。重试队列上的消息将在一定时间后重试。这个想法是服务器暂时关闭,所以请等待再试一次。

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

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

有没有办法立即将这些坏消息移到死信队列?

2 个答案:

答案 0 :(得分:1)

首先,我一直指的是死信队列。在我发布这个问题时,我不知道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客户端。它还意味着在服务器上再设置一个队列以及大量额外的配置部分,用于指定客户端应将消息转发到哪个队列。

答案 1 :(得分:0)

希望我已经理解了你的问题,如果这是我认为你在说什么,那么是的,但你显然需要编程才能做到这一点。但是您需要设置重试量,以便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

How do I handle message failure in MSMQ bindings for WCF

我希望这些链接有所帮助。

相关问题