rabbitmq - 来自 RabbitMQ 的 "Unknown delivery tag"在具有复制队列的集群中确认消息时

标签 rabbitmq cluster-computing failovercluster

我们已经成功使用Rabbit大约一年了。最近升级到v2.6.1,因为我们要使用带有复制消息队列的集群。

我的测试遇到了一个令人费解的行为,对我来说闻起来像兔子的 bug 。揭示这一点的测试正在使用双节点集群。两个节点都运行 v2.6.1。两个节点都有磁盘。两个节点都在 Mac OS 上运行,但我怀疑这是否相关。

我还在运行测试的节点上运行 Alice。该测试使用它以编程方式在其中一个节点上执行 stop_app,因为该测试试图验证如果集群主节点失败,并且从节点被提升以取代它,我们不会丢失消息。

所以,测试有一个小的线程池,它被赋予周期性的任务 1) 发布消息,和 2) 切换 Rabbit 主节点的状态(如果正在运行则停止;如果停止则启动)。其他线程正在使用来自队列的消息。

我正在使用发布者确认,并且我也在确认消费者中的消息(对 channel.basicConsume() 使用 autoAck=false)。

当主节点停止时,我看到生产者和消费者都捕获了 ShutdownSignalException。他们通过尝试重新连接到集群来处理这个问题。这工作正常。重新连接后,他们将继续开展业务。

有时,我看到的是消费者已成功从代理获取消息,并在收到 ShutdownSignalException 时调用 channel.basicAck()。

稍后,当消费者重新连接时,它再次拉下相同的消息。 (消息体用 UUID 标记,所以我知道它是相同的。)这一次,当消费者尝试使用 basicAck() 消息时,它再次获得 ShutdownSignalException,但其中包含以下文本:“回复文本 = PRECONDITION_FAILED - 未知的交付标签 7"。

事实上,这与在主服务器宕机和消费者重新连接之前由代理提供给消费者的交付标签相同。

谷歌搜索表明此事件意味着消费者尝试不止一次确认相同的消息。

可是,怎么会这样呢?如果第一个确认成功,那么消息应该已经从代理的队列中删除,并且消费者不应再次看到相同的消息。

然而,如果第一个确认没有成功,那么消费者不应该因为试图重新确认消息而受到指责。

有人见过这个吗?对我来说,这闻起来像是 Rabbit 复制队列中的一个错误,但我对 Rabbit 还是个新手,所以我愿意相信从集群代理中进行消费有一个微妙之处,我还没有理解!

谢谢,--史蒂夫

最佳答案

我不确定我的情况是否与您的情况相符,但我在重新连接后尝试确认时看到了类似的“未知交付标签”,然后再次收到相同的消息。最初对我来说它看起来像一个错误,但实际上这是预期的行为。 QOS>1 的消费者可能在它的本地缓冲区中有一些消息,并且在重新连接后,交付标记对所有消息都无效。另一方面,即使在重新连接后尝试确认当前消息也没有任何意义,因为该消息在连接丢失时已经自动确认,这就是我再次收到它的原因。

关于rabbitmq - 来自 RabbitMQ 的 "Unknown delivery tag"在具有复制队列的集群中确认消息时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7613247/

相关文章:

azure - 将多次运行提交到 AzureML 上的同一节点

mysql - Spring + Hibernate +数据库连接池和高可用性

sql-server - 故障转移群集上的 SQL Server 2008 Reporting Services

java - RabbitMQ 内存使用量增长过高

java - ColdFusion/RabbitMQ 在factory.newConnection() 上失败

ruby-on-rails - 我可以在带有 AMQP 的 Rails 3 中使用请求/回复 - RPC 模式吗?

java - Hadoop 配置 - 集群

Tomcat 主动被动故障转移

powershell - 无法从独立服务器运行 PowerShell 群集 cmdlet

java - Rabbitmq 连接限制?