【问题标题】:Is Spring-AMQP re-queue message count JVM based?Spring-AMQP 重新排队消息计数是否基于 JVM?
【发布时间】:2015-03-12 16:56:09
【问题描述】:

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

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

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

【问题讨论】:

    标签: java rabbitmq messaging amqp spring-amqp


    【解决方案1】:

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

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

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

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

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

    This answerthis one 有更多详细信息。

    【讨论】:

      猜你喜欢
      • 2016-12-13
      • 1970-01-01
      • 2013-10-14
      • 2017-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-03
      • 2014-11-01
      相关资源
      最近更新 更多