如果手动配置DirectMessageListenerContainer,则忽略spring.rabbitmq.listener.simple.retry.enabled=true

如果手动配置DirectMessageListenerContainer,则忽略spring.rabbitmq.listener.simple.retry.enabled=true,rabbitmq,spring-amqp,spring-annotations,spring-rabbit,Rabbitmq,Spring Amqp,Spring Annotations,Spring Rabbit,我正在尝试使用属性激活rabbitmq上的deadletterqueue spring.rabbitmq.listener.simple.retry.enabled=true spring.rabbitmq.listener.simple.retry.max-attempts=10 当我使用注释时,它工作得很好 public class SimpleConsumer { @RabbitListener(queues = "messages.queue")

我正在尝试使用属性激活rabbitmq上的deadletterqueue

spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.max-attempts=10
当我使用注释时,它工作得很好

public class SimpleConsumer {

    @RabbitListener(queues = "messages.queue")
    public void handleMessage(String message){
        throw new RuntimeException(); 
    }
}
但是,如果我手动配置MessageListenerContainer,它将无法工作

以下是我的配置:

@Bean
SimpleMessageListenerContainer directMessageListenerContainer(
        ConnectionFactory connectionFactory,
        Queue simpleQueue,
        MessageConverter jsonMessageConverter,
        SimpleConsumer simpleConsumer)
{

    return new SimpleMessageListenerContainer(connectionFactory){{
        setQueues(simpleQueue);
        setMessageListener(new MessageListenerAdapter(simpleConsumer, jsonMessageConverter));
       // setDefaultRequeueRejected(false);
    }};

}
如果我将setDefaultRequeueRejected设置为true,它将尝试解析消费者无限时间(如果抛出异常)

若我将setDefaultRequeueRejected设置为false,则尝试解析消费者一次,然后使用deadLetterConsumer

@RabbitListener(queues=“messages.queue”)在引擎盖下使用spring.rabbitmq.listener配置做什么

下面是我在github上的代码


请参阅分支“按配置重试”

它将重试拦截器添加到容器的通知链中。看

Spring Retry提供了几个AOP拦截器,并提供了很大的灵活性来指定重试的参数(尝试次数、异常类型、退避算法等)。SpringAMQP还提供了一些方便的工厂bean,用于以一种方便的形式为AMQP用例创建Spring重试拦截器,并带有强类型回调接口,可用于实现自定义恢复逻辑。有关更多详细信息,请参阅Javadoc和
statefurRetryOperationsInterceptor
无状态RetryOperationsInterceptor
的属性

@Bean
public StatefulRetryOperationsInterceptor侦听器(){
返回RetryInterceptorBuilder.stateful()
.maxports(5)
.backOffOptions(1000,2.0,10000)//初始间隔,乘数,最大间隔
.build();
}
然后将拦截器添加到容器
adviceChain

编辑

请参阅我指给您的文档;您需要将恢复程序添加到拦截器:

当所有重试次数都已用尽时,将调用MessageRecover。RejectAndDontRequeueRecoverer正是这样做的。默认MessageRecoverer使用错误消息并发出警告消息

下面是一个完整的示例:

@springboot应用程序
公共类SO67433138应用程序{
公共静态void main(字符串[]args){
SpringApplication.run(So67433138Application.class,args);
}
@豆子
队列(){
return QueueBuilder.dustable(“so67433138”)
.deadLetterExchange(“”)
.死信路由键(“so67433138.dlq”)
.build();
}
@豆子
队列dlq(){
返回新队列(“so67433138.dlq”);
}
@豆子
SimpleMessageListenerContainer容器(ConnectionFactory cf){
SimpleMessageListenerContainer smlc=新的SimpleMessageListenerContainer(cf);
smlc.setQueueNames(“so67433138”);
setAdviceChain(RetryInterceptorBuilder.stateless()
.maxports(5)
.退避选项(1,000,2.0,10,000)
.recoverer(新的RejectAndDontRequeueRecoverer())
.build());
smlc.setMessageListener(消息->{
System.out.println(新字符串(msg.getBody());
抛出新的运行时异常(“测试”);
});
返回smlc;
}
@RabbitListener(queues=“so67433138.dlq”)
无效dlq(字符串输入){
System.out.println(“来自DLQ:+in”);
}
}

它似乎不起作用,在这里我的代码你有没有尝试过无状态?使用stateful,您需要一个消息id头,以便我们可以查找状态。否,无状态是什么意思?
RetryInterceptorBuilder.stateless()…
。请阅读我指给您的文档;我用一个例子编辑了我的答案。
test
test
test
test
test
2021-05-12 11:19:42.034 WARN 70667 ---[    container-1] o.s.a.r.r.RejectAndDontRequeueRecoverer : Retries exhausted for message ...
...
From DLQ: test