Monday 20 May 2024

Set retry strategy to Http Client

HttpClient offers the HttpRequestRetryStrategy interface as a way for you to customize how the client handles failed requests. This interface lets you define your own rules for retries.

You can control:

1.   When a retry should happen: You can decide whether to retry based on the type of exception encountered or the HTTP status code received from the server.

2.   How many times to retry: You can set a maximum number of retries to prevent endless loops in case of persistent failures.

3.   The delay between retries: You can specify a waiting period between retries to avoid overloading the server or creating unnecessary traffic.

By plugging in your own implementation of HttpRequestRetryStrategy, you gain fine-grained control over how HttpClient behaves in the face of errors.

 

org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy provide a default implementation of the HttpRequestRetryStrategy interface.

 

Example

CloseableHttpClient httpClient = HttpClients
.custom()
.setRetryStrategy(new DefaultHttpRequestRetryStrategy(3, TimeValue.of(2, TimeUnit.SECONDS)))
.build();

The DefaultHttpRequestRetryStrategy constructor provides a pre-configured way to handle retries for HTTP requests. It considers the following:

 

Non-retriable exceptions: The strategy won't attempt a retry if it encounters exceptions like:

1.   InterruptedIOException: The local thread was interrupted.

2.   UnknownHostException: The hostname couldn't be resolved to an IP address.

3.   ConnectException: A connection to the server couldn't be established.

4.   ConnectionClosedException: The connection to the server was closed unexpectedly.

5.   NoRouteToHostException: No route to the server could be found.

6.   SSLException: There was an issue with the SSL handshake.

 

Retriable status codes: The strategy will retry requests that result in these specific HTTP status codes:

1.   SC_TOO_MANY_REQUESTS (429): The server is overloaded and suggests waiting before retrying.

2.   SC_SERVICE_UNAVAILABLE (503): The server is currently unavailable and might be back soon.

 

In essence, this constructor sets up a default behaviour for retrying requests based on common error scenarios. It focuses on retrying when the server might be temporarily unavailable and avoids retrying for issues unrelated to the server's state.

 

Find the below working application.

 

RetryStrategyDemo.java

package com.sample.app.httpclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
import org.apache.hc.core5.util.TimeValue;

public class RetryStrategyDemo {

	public static String inputStreamToString(InputStream inputStream, Charset charSet) throws IOException {

		try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charSet))) {
			return reader.lines().collect(Collectors.joining("\n"));
		}

	}

	public static void main(String[] args) {

		HttpClientResponseHandler<String> responseHandler = new HttpClientResponseHandler<String>() {
			@Override
			public String handleResponse(final ClassicHttpResponse response) throws IOException, ParseException {

				HttpEntity httpEntity = response.getEntity();

				try (InputStream is = httpEntity.getContent()) {
					return inputStreamToString(is, StandardCharsets.UTF_8);
				}

			}
		};

		try (CloseableHttpClient httpClient = HttpClients.custom()
				.setRetryStrategy(new DefaultHttpRequestRetryStrategy(3, TimeValue.of(2, TimeUnit.SECONDS))).build();) {

			ClassicHttpRequest request = new HttpGet("http://localhost:8080/api/v1/retry-test");
			String response = httpClient.execute(request, responseHandler);
			System.out.println(response);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Output

{"status":"200"}

 

Previous                                                    Next                                                    Home

No comments:

Post a Comment