[英]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
希望这些链接对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.