Yossi Shasha
Yossi Shasha

Reputation: 203

spring-cloud-stream retry policy per exception

In the documentation of the spring-cloud-stream project the only retry mechanism that I have saw was a single backoff policy.
The behavior that I would like to achieve is three different retry policies in case that an exception is thrown while consuming a message:

  1. Unrecoverable exception - this kind of messages wouldn't be tried to be processed again.
  2. Recoverable exception - this kind of messages would be retried number of times before being discarded.
  3. Transient exception - this kind of messages would be retried forever.

Is there a way to define a different retry policy for each kind of exception? I know that in spring-kafka there was an ability to provide a RetryTemplate and achieve the above-mentioned behavior.

I thought that maybe with the DLQ mechanism there would be a way to achieve this behavior.

Edit: I am using Kafka as the messaging middleware.

Upvotes: 2

Views: 3499

Answers (3)

emachgyver
emachgyver

Reputation: 1

Given: UnrecoverableException = exception you want to go to the DLQ or discarded right away without retry. TransientException = exception you want to be retried until successful

Something like this in my config class made it work:

@StreamRetryTemplate
public RetryTemplate myRetryTemplate() {
    RetryTemplate myRetry = RetryTemplate.builder()
            .notRetryOn(UnrecoverableException.class)
             //make sure that the exception type is the cause
             //even if it's wrapped 
            .traversingCauses()
            .retryOn(TransientException.class)
            .traversingCauses()
             //custom backoff policy
            .exponentialBackoff(2000, 2, 20000, true)
            .build();
    return myRetry;
}

Upvotes: 0

From Spring Cloud Stream 2.0.0 upwards you can define your own RetryTemplate :

@StreamRetryTemplate
public RetryTemplate myRetryTemplate() {
    return new RetryTemplate();
}

Full doc here : https://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/#_retry_template

Upvotes: 2

Gary Russell
Gary Russell

Reputation: 174554

It is not currently possible to configure the retry to that extent; there is an open new feature request.

However, you can always implement your own logic within your listener, using a RetryTemplate and disable the binder's retries.

If you are using the Rabbit binder, you could use the DLQ and republishToDlq=true and the DLQ messages will contain exception headers. You can then have another app consume those messages and take appropriate action based on the exception type.

Upvotes: 0

Related Questions