Spring-AMQP是否基于JVM重新排队消息计数?

时间:2015-03-12 16:56:09

标签: java rabbitmq messaging amqp spring-amqp

我正在寻找rabbitmq文档,似乎rabbitmq不处理消息重新传递计数。如果我要手动ACK / NACK消息,我需要在内存中保留重试计数(例如,通过使用correlationId作为映射中的唯一键),或者通过在消息中设置我自己的头,并重新传递它(因此把它放在队列的末尾)

然而,这是弹簧处理的情况。具体来说,我指的是RetryInterceptorBuilder.stateful()。maxAttempts(x)。这个计数是特定于JVM的,还是以某种方式操纵消息?

例如,我有一个部署到2台服务器的网络应用程序,其中maxAttempts设置为5.总重新传输计数是否可能在5-9之间,具体取决于重新传递和重新处理的顺序在2台服务器中?

1 个答案:

答案 0 :(得分:6)

Rabbit / AMQP不允许在根据拒绝重新排队时修改消息。

状态(基于messageId)保存在RetryContextCache;默认值为MapRetryContextCache。这并不适合“群集”,因为正如您所说,尝试可能最多为((maxAttempts - 1) * n + 1);加上它会导致内存泄漏(某些服务器上的状态)。您可以在SoftReferenceMapRetryContextCache(构建器中的RetryTemplate)中配置RetryOperations以避免内存泄漏,但这只会解决内存泄漏问题。

您需要使用自定义RetryContextCache和一些持久共享存储(例如redis)。

我通常建议在这种情况下使用无状态恢复 - 重试完全在容器中完成,并且根本不涉及兔子(直到重试耗尽,在这种情况下,消息被丢弃或发送到DLX / DLQ,具体取决于经纪人配置)。

如果您不关心消息顺序(并且我认为您没有给出竞争消费者),一种有趣的技术是拒绝该消息,将其发送到具有到期设置的DLQ,并且当DLQ时消息到期,将其路由回原始队列的尾部(而不是头部)。在这种情况下,可以检查x-death标头以确定它被重试的次数。

This answerthis one有更多详情。