我正在使用RabbitMQ,我有一个包含电子邮件的队列.我的消费者服务将消息排队并尝试发送消息.如果由于任何原因,我的消费者无法发送消息,我想重新排队消息再次发送.我意识到我可以做一个basicNack并将requeue标志设置为true,但是,我不想无限期地重新排列该消息(例如,如果我们的电子邮件系统出现故障,我不想连续重新排队未发送的消息).我想定义有限次数,我可以重新排列要再次发送的消息.但是,当我将它出列并发送一个nack时,我无法在电子邮件消息对象上设置字段.更新的字段不存在于队列中的消息上.还有其他方法可以解决这个问题吗?提前致谢.
在RabbitMQ(以及AMQP协议)中没有像重试尝试这样的功能.
实现重试尝试的可能解决方案限制行为:
Redeliver消息,如果它以前没有重新传递(检查方法的redelivered
参数basic.deliver
- 你的库应该有一些接口)并删除它然后捕获死信交换,然后以某种方式处理.
每次无法处理消息时再次发布它,但设置或增加/减少标题字段,比如说x-redelivered-count
(你可以选择任何你喜欢的名字).要在这种情况下控制重新传输,您必须检查您设置的字段是否达到某个限制(顶部或底部 - 0是我的选择,ttl
在tcp/ip的ip标头中是a-la ).
在Redis,memcache或其他存储中存储消息唯一键(比如uuid,但是你必须在发布消息时手动设置它),甚至在mysql旁边还有重新计数,然后在每次重新传递时增加/减少此值,直到达到限制.
(对于真正的极客)编写插件,将实现您想要的这种行为.
#3的亲是重新传递的消息留在队列头部.如果你有很长的队列或者消息顺序对你很重要,那么这很重要(请注意,重新发送会破坏严格的消息顺序,有关详细信息或SO上的此问题,请参阅官方文档).
PS:
在这个主题中有类似的答案,但在PHP中.看看它,也许它可以帮助你一点(从单词"有多种技术来处理循环再生问题"开始阅读它.