Search code examples
spring-bootspring-amqpspring-rabbit

Retry Configuration for @RabbitListener programatically specify dead-letter queue


I've been trying to find a way to set a retry mechanism to all @RabbitListener's. I've already tried with the properties:

listener:
  auto-startup: true
  concurrency: 1
  max-concurrency: 1
  retry:
    enabled: true
    initial-interval: 1000
    max-attempts: 3
    max-interval: 10000
    multiplier: 2
    stateless: true

And it works fine with the only problem that no error is sent with the message. The only problem I have is that in order to send the messages to a specific DLQ I have to change my queues to add the arguments x-dead-letter-exchange and x-dead-letter-routing-key and that's something I would like to avoid.

So my questions is:

  1. Is there a way to programmatically specify which is the DLQ where the messages should go after exhausting the attempts without re-creating the Queues? Not using arguments x-dead-...

I'm using Spring Boot 1.4.0.RELEASE.


Solution

  • Not via properties.

    You have to override the listener container factory's advice chain with your own retry interceptor - built with a RetryInterceptorBuilder - instead of injecting

    builder.recoverer(new RejectAndDontRequeueRecoverer());
    

    you need to inject an appropriately configured RepublishMessageRecoverer - as well as publishing to an exchange of your choice, it adds additional information (stack trace etc) to the message headers.

    See the SimpleRabbitListenerContainerFactoryConfigurer to see how the default interceptor is built from the properties.

    The republishing recoverer is discussed in this section of the Spring AMQP docs.