Spring-AMQP重新排队消息计数基于JVM吗? [英] Is Spring-AMQP re-queue message count JVM based?

查看:236
本文介绍了Spring-AMQP重新排队消息计数基于JVM吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was poking around the rabbitmq documentation, and it seems that rabbitmq does not handle message redelivery count. If I were to manually ACK/NACK messages, I would need to either keep the retry count in memory (say, by using correlationId as the unique key in a map), or by setting my own header in the message, and redelivering it (thus putting it at the end of the queue)

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

However, this is a case that spring handles. Specifically, I am referring to RetryInterceptorBuilder.stateful().maxAttempts(x). Is this count specific to a JVM though, or is it manipulating the message somehow?

例如,我有一个部署到2台服务器的web-app,maxAttempts设置为5.根据在2台服务器中重新传送和重新处理的顺序,总重新传送计数是否可能在5-9之间?

For example, I have a web-app deployed to 2 servers, with maxAttempts set to 5. Is it possible that the total redelivery count will be anywhere from 5-9, depending on the order in which it is redelivered and reprocessed among the 2 servers?

推荐答案

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

Rabbit/AMQP does not allow modification of the message when requeueing based on rejection.

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

The state (based on messageId) is maintained in a RetryContextCache; the default is a MapRetryContextCache. This is not really suitable for a "cluster" because, as you say, the attempts may be up to ((maxAttempts - 1) * n + 1); plus it will cause a memory leak (state left on some servers). You can configure a SoftReferenceMapRetryContextCache in the RetryTemplate (RetryOperations in the builder) to avoid the memory leak but that only solves the memory leak.

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

You would need to use a custom RetryContextCache with some persistent shared store (e.g. redis).

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

I generally recommend using stateless recovery in this scenario - the retries are done entirely in the container and do not involve rabbit at all (until retries are exhausted, in which case the message is discarded or sent to the DLX/DLQ depending on broker configuration).

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

If you don't care about message order (and I presume you don't given you have competing consumers), an interesting technique is to reject the message, send it to a DLQ with an expiry set and, when the DLQ message expires, route it back to the tail of original queue (rather than the head). In that case, the x-death header can be examined to determine how many times it has been retried.

这个答案这个有更多细节。

这篇关于Spring-AMQP重新排队消息计数基于JVM吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆