如何处理wcf的msmq绑定中的消息失败?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

我创建了一个WCF服务,并使用netMsmqBinding绑定。

这是一个简单的服务,它将Dto传递给我的服务方法,并且不期望得到响应。该消息被放置在MSMQ中,并且一旦被拾取,就插入到数据库中。

确保没有数据丢失的最佳方法是什么?

我已经尝试了以下2种方法:

  1. 抛出一个异常 这将信息置于死信队列中进行手动阅读。当我的服务启动时,我可以处理这个
  2. 在绑定上设置receiveRetryCount =“3” 3次尝试后 - 即时发生,这似乎将消息留在队列中,但错误我的服务。重新启动我的服务将重复此过程。

理想情况下,我想要做到以下几点:

尝试处理消息

  • 如果失败,请等待5分钟,然后重试。
  • 如果该过程失败3次,请将消息移至死信队列。
  • 重新启动该服务会将所有来自死信队列的消息推回到队列中,以便处理它。

我可以做到这一点吗?如果是这样如何?你能指点我一些关于如何最好地利用WCF和MSMQ为我的情景的好文章。

一些额外的信息

我在Windows XP和Windows Server 2003上使用MSMQ 3.0。不幸的是,我无法使用针对MSMQ 4.0和Vista / 2008的内置毒讯消息支持。

提问于
用户回答回答于

SDK中有一个示例。基本上,它所做的是将一个IErrorHandler实现附加到服务,当WCF将消息声明为“毒药”(即所有配置的重试已用尽时)将捕获该错误。该示例所做的是将消息移动到另一个队列,然后重新启动与该消息关联的ServiceHost(因为在发现毒害消息时它将发生故障)。

这不是一个非常漂亮的示例,但它可能很有用。但是有一些限制:

1-如果有多个端点与您的服务相关联(即通过多个队列公开),则无法知道有毒邮件到达哪个队列。如果只有一个队列,这不会成为问题。我还没有看到任何官方的解决方法,但我已经尝试了一种可能的替代方法,我在这里记录了这些方法:http : //winterdom.com/weblog/2008/05/27/NetMSMQAndPoisonMessages.aspx

2-一旦问题消息被移动到另一个队列中,它就成为你的责任,所以一旦超时完成(或者将一个新服务附加到该队列来处理它),你就可以将它移回到处理队列。

说实话,无论是哪种情况,你都在寻找一些“手动”的工作,而WCF本身并没有涉足。

我最近一直在研究一个不同的项目,在这个项目中,我有明确控制重试次数的要求,而我目前的解决方案是创建一组重试队列,并在重试队列和主处理队列之间手动移动消息,一组计时器和一些启发式算法,只是使用原始的System.Messaging来处理MSMQ队列。它似乎很好地工作,但如果你这样做,有几个陷阱。

用户回答回答于

我认为MSMQ(仅在Vista上可用)可能可以这样做:

<bindings>
    <netMsmqBinding>
        <binding name="PosionMessageHandling"
             receiveRetryCount="3"
             retryCycleDelay="00:05:00"
             maxRetryCycles="3"
             receiveErrorHandling="Move" />
    </netMsmqBinding>
</bindings>

WCF将在第一次呼叫失败后立即重试ReceiveRetryCount次。批处理失败后,该消息被移至重试队列。RetryCycleDelay延迟一分钟后,消息从重试队列移至端点队列,并重试批次。这将会重复MaxRetryCycle时间。如果所有失败的消息根据可以移动的receiveErrorHandling处理(毒害队列),拒绝,丢弃或错误

顺便说一下关于WCF和MSMQ的一个好文本是Juval Lowy的Progammig WCF书的第9章

扫码关注云+社区