我已经创建了一个WCF服务并且正在使用netMsmqBinding绑定.
这是一个简单的服务,它将Dto传递给我的服务方法,并且不期望响应.该消息放在MSMQ中,一旦被选中插入数据库.
确保没有数据丢失的最佳方法是什么.
我尝试了以下两种方法:
抛出一个例外
这会将消息放入死信队列中以供手动阅读.我的工作开始时我可以处理这个
在绑定上设置receiveRetryCount ="3"
经过3次尝试 - 即时发生,这似乎将消息留在队列中,但是我的服务出错了.重新启动我的服务会重复此过程.
理想情况下,我想做以下事项:
尝试处理消息
如果此操作失败,请等待5分钟以查看该消息,然后重试.
如果该过程失败3次,请将消息移至死信队列.
重新启动服务会将死信队列中的所有消息推回到队列中,以便可以对其进行处理.
我能做到吗?如果是这样的话?你能否指出我有关如何最好地利用WCF和MSMQ为我的给定sceneria的任何好文章.
任何帮助将非常感激.谢谢!
一些额外的信息
我在Windows XP和Windows Server 2003上使用MSMQ 3.0.不幸的是,我不能使用针对MSMQ 4.0和Vista/2008的内置有害消息支持.
我认为使用MSMQ(只能在Vista上使用),您可以这样做:
第一次调用失败后,WCF将立即重试ReceiveRetryCount次数.批处理失败后,邮件将移至重试队列.在RetryCycleDelay分钟延迟之后,消息从重试队列移动到端点队列,并重试批处理.这将是MaxRetryCycle重复的时间.如果全部失败,则根据receiveErrorHandling处理消息,该错误可以移动(到毒性队列),拒绝,丢弃或错误
顺便说一句关于WCF和MSMQ的好文章是来自Juval Lowy的Progammig WCF书的第9章
SDK中有一个示例可能对您的案例有用.基本上,它所做的是将IErrorHandler实现附加到您的服务,当WCF声明消息为"poison"时(即当所有已配置的重试都已用尽时)将捕获该错误.该示例所做的是将消息移动到另一个队列,然后重新启动与消息关联的ServiceHost(因为在发现有害消息时它会出现故障).
这不是一个非常漂亮的样本,但它可能很有用.但是有一些限制:
1-如果有多个端点与您的服务相关联(即通过多个队列暴露),则无法知道有毒消息到达哪个队列.如果您只有一个队列,这将不会成为问题.我没有看到任何正式的解决方法,但我已经尝试了一种可能的替代方案,我在这里记录了: http //winterdom.com/weblog/2008/05/27/NetMSMQAndPoisonMessages.aspx
2-一旦问题消息被移动到另一个队列,它就成了你的责任,所以你需要在超时完成后将它移回处理队列(或者将新服务附加到该队列来处理它).
说实话,在任何一种情况下,你都在看一些WCF根本没有覆盖的"手动"工作.
我最近一直致力于一个不同的项目,我需要明确控制重试的频率,我当前的解决方案是创建一组重试队列,并在重试队列和主处理队列之间手动移动消息.一组定时器和一些启发式方法,只需使用原始的System.Messaging来处理MSMQ队列.它似乎运行得很好,但如果你这样做有几个问题.