spring-bootrabbitmqspring-amqpspring-retryretrypolicy

How to implement Retry logic in RabbitMQ?


In my project I'm setting SimpleRetryPolicy to add custom exception and RetryOperationsInterceptor which is consuming this policy.

@Bean
    public SimpleRetryPolicy rejectionRetryPolicy() {
        Map<Class<? extends Throwable>, Boolean> exceptionsMap = new HashMap<Class<? extends Throwable>, Boolean>();
        exceptionsMap.put(DoNotRetryException.class, false);//not retriable
        exceptionsMap.put(RetryException.class, true); //retriable
        return new SimpleRetryPolicy(3, exceptionsMap, true);
    }

    @Bean
    RetryOperationsInterceptor interceptor() {
        return RetryInterceptorBuilder.stateless()
                .retryPolicy(rejectionRetryPolicy())
                .backOffOptions(2000L, 2, 3000L)
                .recoverer(
                        new RepublishMessageRecoverer(rabbitTemplate(), "dlExchange", "dlRoutingKey"))
                .build();
    }  

But with these configurations retry is not working for both RetryException and DoNotRetryException, where I want RetryException to be retried finite number of time and DoNotRetryException to send to DLQ

Please help with the issue, I'm attaching repo link if in case of need.

https://github.com/aviralnimbekar/RabbitMQ/tree/main/src


Solution

  • Your GlobalErrorHandler does its logic before the retry happens and you override there an exception with the AmqpRejectAndDontRequeueException. And looks like you do there a publish to DLX. Consider to move your GlobalErrorHandler logic to a more general ErrorHandler for the factory.setErrorHandler(); instead.

    See more info in docs: https://docs.spring.io/spring-amqp/reference/html/#exception-handling

    UPDATE

    After removing errorHandler = "globalErrorHandler" from your @RabbitListener, I got this in logs:

    2022-08-03 16:02:08.093  INFO 16896 --- [nio-8080-exec-4] c.t.r.producer.RabbitMQProducer          : Message sent -> retry
    2022-08-03 16:02:08.095  INFO 16896 --- [ntContainer#0-1] c.t.r.consumer.RabbitMQConsumer          : Retrying message...
    2022-08-03 16:02:10.096  INFO 16896 --- [ntContainer#0-1] c.t.r.consumer.RabbitMQConsumer          : Retrying message...
    2022-08-03 16:02:13.099  INFO 16896 --- [ntContainer#0-1] c.t.r.consumer.RabbitMQConsumer          : Retrying message...
    2022-08-03 16:02:13.100  WARN 16896 --- [ntContainer#0-1] o.s.a.r.retry.RepublishMessageRecoverer  : Republishing failed message to exchange 'dlExchange' with routing key dlRoutingKey
    2022-08-03 16:02:17.736  INFO 16896 --- [nio-8080-exec-5] c.t.r.producer.RabbitMQProducer          : Message sent -> 1231231
    2022-08-03 16:02:17.738  INFO 16896 --- [ntContainer#0-1] c.t.r.consumer.RabbitMQConsumer          : sending into dlq...
    2022-08-03 16:02:17.739  WARN 16896 --- [ntContainer#0-1] o.s.a.r.retry.RepublishMessageRecoverer  : Republishing failed message to exchange 'dlExchange' with routing key dlRoutingKey
    

    Which definitely reflects your original requirements.