Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring RestTemplate: Exponential Backoff retry policy

I'm reading up on GCM: https://developers.google.com/cloud-messaging/server

and one of the requirements is that the server needs to be able to:

  • handle requests and resend them using exponential back-off.

I use Spring RestTemplate for my backend which comes from Spring Boot. There doesn't seem to be a method which I can use to set my retry policy in the docs: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

Also when I googled, I found the RetryTemplate, but it is part of Spring Batch and doesn't extend RestTemplate which makes me think that it is not supposed to be used for Rest operations, but rather Spring Batch operations like processing large amount of transactions: http://docs.spring.io/spring-batch/2.1.x/apidocs/org/springframework/batch/retry/support/RetryTemplate.html

Is there a way I can use exponential backoff with Spring RestTemplate?

like image 638
Simon Avatar asked Aug 09 '15 16:08

Simon


People also ask

How do you add retry logic to Resttemplate?

Implementing the Retry Logic. First, you need to enable Spring Retry. You can achieve this by adding the @EnableRetry annotation to your @SpringBootApplication or @Configuration class. You can now use @Retryable to annotate any method to be a candidate or retry and @Recover to specify fallback methods.

What is backoff in spring Retry?

Spring Uniform Random Backoff The above logic means that the delay period will be random based on initial delay and maxDelay variables set from the retry configuration that you implement.

What is retry mechanism in spring boot?

Spring Retry provides an ability to automatically re-invoke a failed operation. This is helpful where the errors may be transient (like a momentary network glitch).

What is FixedBackOffPolicy?

I see FixedBackOffPolicy as an implementation of BackOffPolicy that pauses for a fixed period of time before continuing and ExponentialBackOffPolicy as an implementation of BackOffPolicy that increases the back off period for each retry attempt in a given set.


1 Answers

Good day!

I guess, desired behavior could be achived by implementing custom Sleeper class.

Next you need to set this sleeper to BackOffPolicy as follows:

public class RetryTest {

  public static final Logger LOG = LoggerFactory.getLogger(RetryTemplate.class);

  @org.junit.Test
  public void testRT() {
    RetryTemplate retryTemplate = new RetryTemplate();
    final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(5);
    retryTemplate.setRetryPolicy(retryPolicy);

    Sleeper sleeper = new Sleeper() {
      private long timeToSleep = 0;
      @Override
      public void sleep(long timeout) throws InterruptedException {
        if (timeToSleep ==0) {
          timeToSleep = timeout;
        } else {
          timeToSleep = (long) (timeToSleep * Math.E);
        }
        LOG.warn("sleeping for: {}", timeToSleep);
        Thread.sleep(timeToSleep);
      }
    };
    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy().withSleeper(sleeper);
    retryTemplate.setBackOffPolicy(backOffPolicy);
    retryTemplate.execute(new RetryCallback<Void, ResourceAccessException>() {
      @Override
      public Void doWithRetry(RetryContext retryContext) throws ResourceAccessException {
        LOG.debug(">RetryCount: {}", retryContext.getRetryCount());
        new RestTemplate().getForObject("https://unreachable.host", String.class);
        return null;
      }
    });
  }
}

Also there is ExponentialBackOffPolicy by spring-retry.

Hope this would help.

like image 188
Konstantin Konyshev Avatar answered Oct 25 '22 22:10

Konstantin Konyshev