Is Spring-AMQP re-queue message count JVM based?

元气小坏坏 提交于 2019-12-22 08:13:10

问题


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)

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?

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?


回答1:


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

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.

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

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).

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.

This answer and this one have more details.



来源:https://stackoverflow.com/questions/29015793/is-spring-amqp-re-queue-message-count-jvm-based

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!