Retry and Backoff
Rqueue is a polling-based library that interacts with Redis to retrieve messages. These interactions can fail due to Redis server stress, outages, connection timeouts, or network instability. To avoid overloading Redis during such failures, you can configure a back-off interval.
When a command fails, the poller will wait for the duration specified by backOffTime in the SimpleRqueueListenerContainerFactory before trying again. The default back-off time is 5 seconds.
Disabling Retries
If you want to prevent Rqueue from retrying specific task failures, you can use one of the following methods:
-
Using the
@RqueueListenerAnnotation: Specify exceptions in thedoNotRetryattribute. Rqueue will not retry the task if it fails with any of these exceptions.
public class MessageListener {
@RqueueListener(value = "sms", doNoRetry = {Exception1.class, Exception2.class})
public void onMessage(Sms sms) {
log.info("Sms: {}", sms);
}
}
-
Returning
-1from a Custom Backoff: If you implement a customTaskExecutionBackOff, returning-1signals Rqueue to stop all further retry attempts for that message.
Note: Messages handled this way are neither retried nor moved to the Dead Letter Queue.
Task Execution Backoff
When a message handler fails, the message can be retried immediately, delayed for a future retry, moved to a dead letter queue, or dropped.
Immediate Retries
To retry a message immediately within the same polling cycle, set rqueue.retry.per.poll to a positive integer (e.g., 2). This will cause the message to be retried twice in quick succession before being returned to the queue.
Delayed Retries (Exponential/Linear Backoff)
By default, Rqueue uses a linear backoff with a 5-second delay. You can customize this by providing a TaskExecutionBackOff implementation. Rqueue includes built-in options like FixedTaskExecutionBackOff and ExponentialTaskExecutionBackOff.
public class RqueueConfiguration {
@Bean
public SimpleRqueueListenerContainerFactory simpleRqueueListenerContainerFactory() {
SimpleRqueueListenerContainerFactory factory = new SimpleRqueueListenerContainerFactory();
// ...
factory.setTaskExecutionBackOff(getTaskExecutionBackoff());
return factory;
}
private TaskExecutionBackOff getTaskExecutionBackoff() {
// Example: 2 seconds delay, 2 retries
// return new FixedTaskExecutionBackOff(2_000L, 2);
// Example: Exponential backoff starting at 2s, max 10m
// return new ExponentialTaskExecutionBackOff(2_000L, 10 * 60_000L, 2, 200);
}
}