You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot AMQP:如何为不同异常配置差异化重试策略

解决方案

可以通过自定义重试异常策略实现你的需求:让AmqpRejectAndDontRequeueException和MessageConversionException直接进入DLQ,其他异常执行指数退避重试后再转入DLQ。具体步骤如下:

1. 保留原有重试配置

继续使用你在application.yml中定义的指数退避参数,这些参数会作为重试的基础规则:

spring:  
  rabbitmq:
    listener:
      simple:
        retry:
          enabled: true
          initial-interval: 3s
          max-attempts: 5
          max-interval: 10s
          multiplier: 2

2. 自定义重试异常分类器

创建Spring配置类,通过SimpleRetryPolicy指定不需要重试的异常列表,并将其关联到重试模板,最终覆盖默认的监听器容器工厂:

import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMqRetryConfig {

    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory,
            MessageConverter messageConverter,
            MessageRecoverer messageRecoverer) {

        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(messageConverter);
        
        // 构建重试策略:指定不重试的异常
        Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
        // 这两种异常直接拒绝,不重试
        retryableExceptions.put(AmqpRejectAndDontRequeueException.class, false);
        retryableExceptions.put(MessageConversionException.class, false);
        // 其他异常允许重试
        retryableExceptions.put(Throwable.class, true);

        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setRetryableExceptions(retryableExceptions);
        retryPolicy.setMaxAttempts(5); // 与yml配置的max-attempts保持一致

        // 构建重试模板,绑定指数退避策略和自定义异常规则
        RetryTemplate retryTemplate = new RetryTemplate();
        retryTemplate.setRetryPolicy(retryPolicy);
        
        // 配置指数退避策略,对应yml中的参数
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(3000); // 3s
        backOffPolicy.setMaxInterval(10000); // 10s
        backOffPolicy.setMultiplier(2);
        retryTemplate.setBackOffPolicy(backOffPolicy);

        factory.setRetryTemplate(retryTemplate);
        // 设置重试耗尽后的消息恢复器(转发到DLQ)
        factory.setMessageRecoverer(messageRecoverer);

        return factory;
    }

    // 配置消息恢复器,将重试耗尽的消息转发到DLQ
    @Bean
    public MessageRecoverer republishMessageRecoverer(ConnectionFactory connectionFactory) {
        // 替换为你实际的DLQ交换机和路由键
        return new RepublishMessageRecoverer(connectionFactory, "your-dlq-exchange", "your-dlq-routing-key");
    }
}

3. 关键说明

  • SimpleRetryPolicy通过retryableExceptions映射表明确规则:false表示该异常不触发重试,直接进入DLQ;true表示允许重试。
  • 对于AmqpRejectAndDontRequeueException,框架本身会识别该异常并直接拒绝消息,自定义重试策略可确保它完全跳过重试流程;
  • MessageConversionException属于消息接收阶段的转换异常,将其排除在重试列表后,会直接触发消息转发到DLQ;
  • 重试次数耗尽后,RepublishMessageRecoverer会将消息转发到你预先配置的DLQ,需替换代码中对应的交换机和路由键。

内容的提问来源于stack exchange,提问作者Igor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:57:26