We don’t give up easily as developers, and neither do our services.
This blog will show you how to retry an HTTP request even if it fails until a condition is met.
The service that has some data currently listens on port 3333 and has one endpoint called /hello, but it’s down and returns 503 😢.
Our service needs to have an retry mechanism in place so it will retry couple of times until it throws an error. In order to achieve this we will use spring’s retry module (former part of spring batch).
@SpringBootApplication
@EnableRetry
public class RetryingHttpApplication {
@Autowired
private AmazingHttpClient amazingHttpClient;
public static void main(String[] args) {
SpringApplication.run(RetryingHttpApplication.class, args);
}
@Bean
CommandLineRunner commandLineRunner(){
return new CommandLineRunner() {
@Override
public void run(String... args) throws Exception {
amazingHttpClient.getData();
}
};
}
}
Once the module is in your classpath, you can enable the retry mechanism by annotations the application entrypoint with EnableRetry.
The command line runner invokes the getData() method with is used to communicate with the service which contains the data we need.
The method inside the http client looks like this
public String getData() {
var restTemplateBuilder = new RestTemplateBuilder();
RestTemplate template = restTemplateBuilder.build();
return template.getForObject(
"http://localhost:3333/hello",
String.class
);
}
Now we want to apply the following rule when retrying
<i>If any exception is thrown while trying to read the data, retry every 2 seconds for 5 attempts.</i>
@Retryable(retryFor = Exception.class, backoff = @Backoff(delay = 2000L), maxAttempts = 5)
public String getData() {
var restTemplateBuilder = new RestTemplateBuilder();
RestTemplate template = restTemplateBuilder.build();
return template.getForObject(
"http://localhost:3333/hello",
String.class
);
}
If you run the application now, you should see something like this in the logs which means that the service itself is trying 5 times to talk to the destination service.
2023-02-13T20:48:07.664+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=0
2023-02-13T20:48:09.685+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=1
2023-02-13T20:48:09.685+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=1
2023-02-13T20:48:11.688+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=2
2023-02-13T20:48:11.688+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=2
2023-02-13T20:48:13.696+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=3
2023-02-13T20:48:13.697+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=3
2023-02-13T20:48:15.705+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=4
2023-02-13T20:48:15.706+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Retry: count=4
2023-02-13T20:48:15.708+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Checking for rethrow: count=5
2023-02-13T20:48:15.708+01:00 DEBUG 50543 --- [ main] o.s.retry.support.RetryTemplate : Retry failed last attempt: count=5