RabbitMQ中的建议链不起作用

时间:2016-04-01 14:09:38

标签: spring-amqp

我想实现重试功能(当消费者出现问题时)3次,然后消息应该转到另一个队列(死信交换)。我已将队列/交换配置为如下

常规消息交换名称:test_exchange 消息队列:test_queue test_queue使用路由键test_queue

绑定到test_exchange

死信交换名:test_dlq_exchange 死信息队列:test_dlq_queue test_dlq_queue使用路由键test_dlq_queue绑定到test_dlq_exchange

在RabbitMQ UI控制台中,我将“x-dead-letter-exchange”配置为“test_exchange”

以下是SimpleMessageListenerContainer的代码

Foldable

我的自定义消息监听器是消息驱动的POJO,它只有我的MessageObject。

由于我使用了有状态,因此我启用了createMessageIds(true)。在我的消息监听器中,我再次调用targetobject的方法。启动容器后,流程将循环

即将消息发布到队列 - >消息侦听器根据某些异常调用目标方法 - >再次将消息发布到队列 - >消息监听器调用目标方法...等。它没有将消息推送到死信交换/队列并且进入无限循环。

在日志中我看到如下

  @Bean 
    SimpleMessageListenerContainer getMessageListenerContainer(){
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setQueueNames("test_queue");

    MessageListenerAdapter adapter = new MessageListenerAdapter();
     //configured my message listener class 
     //configured Jackson2JsonMessageConverter as converter
     container.setMessageListener(adapter);
     container.setAdviceChain(new Advice[] {retryAdvice()}
     return container;
    }

    //configuration for retryAdvice

     @Bean 
     public MethodInterceptor retryAdvice{

        ExponentialBackOffPolicy backoffPolicy = new ExponentialBackOffPolicy();
        backoffPolicy.setInitialInterval(10);
        backoffPolicy.setMaxInterval(1000);
        backoffPolicy.setMultiplier(2);
        RabbitTemplate retryTemplate = new RabbitTemplate(connectionFactory());
        retryTemplate.setQueue("test_dl_queue");
        return RetryInterceptorBuilder
                    .stateful()
                    .backOffPolicy(backoffPolicy)
                    .maxAttempts(3)
                    .recoverer(
                       new RepublishMessageRecoverer
                       (retryTemplate,"test_dl_exchange","test_queue")).build();
    }  

有人可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

由于您使用的是RepublishMessageRecoverer,因此在代理上配置DLX / DLQ不会执行任何操作。为了路由到DLQ,您需要RejectAndDontRequeueRecover - 当重试用尽时,消息将被发送到DLX / DLQ。

看起来你要重新发布到同一个队列

(retryTemplate,"test_dl_exchange","test_queue"))

因此无限循环。