如何在 RabbitMQ 中设置重试次数?

时间:2023-04-27
本文介绍了如何在 RabbitMQ 中设置重试次数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在使用 RabbitMQ,并且我有一个保存电子邮件消息的队列.我的消费者服务使消息出队并尝试发送它们.如果出于任何原因,我的消费者无法发送消息,我想将消息重新排队以再次发送.我意识到我可以做一个 basicNack 并将 requeue 标志设置为 true,但是,我不想无限期地重新排队消息(例如,如果我们的电子邮件系统出现故障,我不想不断地重新排队未发送的消息).我想定义一个有限的次数,我可以将消息重新排队以再次发送.但是,当我将其出列并发送 nack 时,我无法在电子邮件对象上设置字段.队列中的消息上不存在更新的字段.还有其他方法可以解决这个问题吗?提前致谢.

I am using RabbitMQ and I have a queue that holds email messages. My consumer service de-queues messages and attempts to send them. If, for any reason, my consumer cannot send the message, I would like to re-queue the message to send again. I realize I can do a basicNack and set the requeue flag to be true, however, I don't want to requeue the message indefinitely (say, if our email system goes down, I don't want to continuously requeue unsent messages). I would like to define a finite number of times that I can requeue the message to be sent again. I can't set a field on the email message object, however, when I dequeue it and send a nack. The updated field is not present on the message in the queue. Is there any other way in which I can approach this? Thanks in advance.

推荐答案

在 RabbitMQ(以及 AMQP 协议)中没有像重试尝试这样的功能.

There are no such feature like retry attempts in RabbitMQ (as well as in AMQP protocol).

实现重试尝试限制行为的可能解决方案:

Possible solution to implement retry attempts limit behavior:

  1. 如果之前没有重新传递消息,则重新传递消息(检查 basic.deliver 方法上的 redelivered 参数 - 你的库应该有一些接口)并删除它然后在死信交换中捕获,然后以某种方式处理.

  1. Redeliver message if it was not previously redelivered (check redelivered parameter on basic.deliver method - your library should have some interface for this) and drop it and then catch in dead letter exchange, then process somehow.

每次无法处理消息时再次发布它,但设置或增加/减少标头字段,例如 x-redelivered-count(不过,您可以选择任何您喜欢的名称).要在这种情况下控制重新交付,您必须检查您设置的字段是否达到某个限制(顶部或底部 - 0 是我的选择,a-la ttl in ip header from tcp/ip).

Each time message cannot be processed publish it again but set or increment/decrement header field, say x-redelivered-count (you can chose any name you like, though). To get control over redeliveries in this case you have to check the field you set whether it reaches some limit (top or bottom - 0 is my choise, a-la ttl in ip header from tcp/ip).

将消息唯一键(比如 uuid,但您必须在发布消息时手动设置)存储在 Redis、memcache 或其他存储中,甚至在 mysql 中与重新传递计数一起存储,然后在每次重新传递时递增/递减这个值直到达到极限.

Store message unique key (say uuid, but you have to set it manually when you publish message) in Redis, memcache or other storage, even in mysql alongside with redeliveries count and then on each redelivery increment/decrement this value until it reach the limit.

(对于真正的极客)编写将实现您想要的此类行为的插件.

(for real geeks) write plugin that will implement such behavior like you want.

#3 的优点是重新传递的消息保留在队列头中.如果您排长队或消息顺序对您很重要,这一点很重要(请注意,重新发送会破坏严格的消息顺序,有关详细信息,请参阅官方文档或 this question on SO).

The pro of #3 is that redelivered message stay in queue head. This is important if you have long queue or if message order is important for you (note, that redeliveries will break strict messages order, see official docs for details or this question on SO).

附注:

此主题中有类似答案,但在php中.看一遍,也许对你有一点帮助(从有多种技术可以处理循环重新传递问题"开始阅读..

There is similar answer in this topic, but in php. Look through it, maybe it helps you a bit (start reading it from words "There are multiple techniques to deal with cycle redeliver problem".

这篇关于如何在 RabbitMQ 中设置重试次数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:WebClient 设置标头 下一篇:RabbitMQ 异步支持

相关文章