stritzi stritzi - 2 years ago 286
Java Question

Spring AMQP @RabbitListener custom retry on business error best practice

Following scenario: I have a

@RabbitListener
picking up messages from RabbitMQ. Sometimes the message runs into an error because I can not find the related business object. In this case I have no possibility to reply to the sender so I just want to ignore this message after certain amount of retry.

My solution: In my
@RabbitListener
whenever it is not possible to find the business object I throw a custom runtime exception. In my configuration I have a
RetryOperationsInterceptor
with max attempts and a custom recoverer.

What is the best practice for handling such cases? Can I configure diffrent recoverer class when having more than one
@RabbitListener
?

See my configuraion:

@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setMessageConverter(new CustomMessageConverter());
factory.setConnectionFactory(connectionFactory());
factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
factory.setConcurrentConsumers(1);
factory.setMaxConcurrentConsumers(20);

Advice[] adviceChain = new Advice[] { interceptor() };
factory.setAdviceChain(adviceChain);
return factory;
}

@Bean
RetryOperationsInterceptor interceptor() {
return RetryInterceptorBuilder.stateless()
.maxAttempts(5)
.recoverer(new CustomRejectAndRecoverer())
.build();
}


And this is my
CustomRejectAndRecoverer
:

public class CustomRejectAndRecoverer implements MessageRecoverer {

@Override
public void recover(Message message, Throwable cause) {
if (ExceptionUtils.getRootCause(cause) instanceof BusinessObjectNotFoundRuntimeException) {
throw new ListenerExecutionFailedException("Retry Policy Exhausted",
new AmqpRejectAndDontRequeueException(cause), message);
}
}
}

Answer Source

You currently need a different container factory for each different retry configuration.

In 2.0, we have added a new errorHandler attribute to the annotation so each listener can have a customized error handler, regardless of the container factory it was created by.

This was in the first milestone release; the current milestone is M2 and M3 will be out shortly. The GA release is expected in June.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download