我使用的是RabbitMQ,我有一个队列来保存邮箱.我的消费者服务对消息进行排队,并try 发送它们.如果由于任何原因,我的消费者无法发送该消息,我希望重新排队发送该消息.我意识到我可以进行基本确认并将requeue标志设置为true,但是,我不想无限期地重新查询消息(比如,如果我们的邮箱系统出现故障,我不想继续重新查询未发送的消息).我想定义一个有限的次数,我可以再次发送消息.然而,当我将其出列并发送nack时,我无法在邮箱对象上设置字段.队列中的消息上不存在更新的字段.我还有别的办法吗?提前谢谢.

推荐答案

RabbitMQ(以及AMQP协议)中没有类似重试try 的功能.

实施重试try 限制行为的可能解决方案:

  1. 重新传递消息,如果之前没有重新传递(判断basic.deliver方法上的redelivered参数-您的库应该有一些接口),将其丢弃,然后捕捉到dead letter exchange,然后以某种方式进行处理.

  2. 每次无法处理消息时,将其再次发布,但要设置或递增/递减标题字段,例如x-redelivered-count(不过,您可以 Select 任何喜欢的名称).在这种情况下,为了控制重新交付,您必须判断您设置的字段是否达到某个限制(顶部或底部-0是我的 Select ,tcp/ip的ip头中的a-la ttl).

  3. 将邮件唯一键(比如UUID,但发布邮件时必须手动设置)存储在Redis、Memcache或其他存储中,即使在MySQL中也是如此,同时还会进行重新投递计数,然后在每次重新投递时递增/递减此值,直到达到限制.

  4. (对于真正的极客)编写插件,实现你想要的行为.

#3的优点是重新传递的消息保持在队列头.如果你有很长的队列,或者消息顺序对你很重要,这一点很重要(请注意,重新发送将打破严格的消息顺序,请参阅官方文档了解详细信息或this question on SO).

P.S.:

在这个主题中有similar answer个,但是在php中.通读一遍,也许它对你有点帮助(从单词"There are multiple techniques to deal with cycle redeliver problem"开始阅读).

.net相关问答推荐

在计算Total毫秒时,.NET TimeSpan类中是否存在错误?

如何在dotnet中使用OpenTelemetry Prometheus导出器导出多个版本的度量?

使用CLR将数据从Excel导入SQL Server时出错

保存时不保留 XML 格式

在 .NET 中使用 AES 解密时缺少后半字节

更改列表中的值

CustomControl 计算自己的宽度和高度 - 使用 bounds.Height=0 调用 ArrangeOverride

防止在 .NET 上构建路径中的反斜杠以进行跨平台部署

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

Web API 中基于令牌的身份验证,无需任何用户界面

如何创建 LINQ to SQL 事务?

为什么 C# 不允许像 C++ 这样的非成员函数

如何防止和/或处理 StackOverflowException?

如何明智地使用 StringBuilder?

什么是 Hashtable 的通用版本?

如何将枚举值序列化为 int?

风格上的差异:IDictionary vs Dictionary

log4net的正确使用方法(记录器命名)

.NET 高级别的 .NET 4.0 和 .NET 4.5 的区别

例外:不支持 URI 格式