0

我正在尝试使用 Spring 的 StatefulRetryOperationsInterceptor 为 RabbitMQ 实现示例重试机制。

如文档中所述,我需要设置消息密钥生成器,因为消息 ID 不存在。我不明白的是每条消息生成的唯一 ID 的真正用法。即,当我使用以下实现时,重试没有任何问题:

StatefulRetryOperationsInterceptor interceptor = 
RetryInterceptorBuilder.stateful()
           .maxAttempts(3)
           .backOffOptions(2000, 1, 2000)
           .messageKeyGenerator(
            new MessageKeyGenerator() {
              @Override
              public Object getKey(Message message) {
                return 1;
              }
           );
container.setAdviceChain(new Advice[] {interceptor});
4

1 回答 1

1

有状态重试需要原始消息在某种程度上是唯一的——因此可以确定消息的重试“状态”——最简单的方法是让消息发布者添加一个唯一的消息 ID 标头。

但是,您的邮件正文或其他标头中的某些内容可能会用于唯一标识邮件。输入MessageKeyGenerator用于确定唯一 ID 的内容。

使用常量(在您的情况下为 1)将不起作用,因为每条消息都具有相同的消息密钥,并且都将被视为同一消息的传递(从重试的角度来看)。

该框架确实提供了一个MissingMessageIdAdvice可以为有状态重试提供有限支持(如果在重试建议之前添加到建议链)。它将 messageId 添加到传入消息。

“有限”表示不提供完整的有状态重试支持 - 仅允许一次重新传递尝试。

如果重新传递失败,则消息被拒绝,这会导致它被丢弃或路由到 DLX/DLQ(如果这样配置)。在所有情况下,“临时”状态都会从缓存中删除。

通常,如果需要完全重试支持并且没有messageId属性并且无法生成带有 的唯一键MessageKeyGenerator,我建议使用无状态重试。

于 2016-04-18T03:36:03.280 回答