Could somebody share how to configure modern HttpClient 4.5.3 to retry failed requests and wait for some time before each retry?
So far it looks like I got it correctly that .setRetryHandler(new DefaultHttpRequestRetryHandler(X, false))
will allow to retry requests X times.
But I cannot understand how to configure backoff: .setConnectionBackoffStrategy()
/ .setBackoffManager()
according to JavaDocs regulate something else, not timeout between retries.
About the dynamic delay, I want to suggest this:
CloseableHttpClient client = HttpClientBuilder.create()
.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
return executionCount <= maxRetries ;
}
})
.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
int waitPeriod = 100;
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
waitPeriod *= 2;
return executionCount <= maxRetries &&
response.getStatusLine().getStatusCode() >= 500; //important!
}
@Override
public long getRetryInterval() {
return waitPeriod;
}
})
.build();
Appendix: Please note, that ServiceUnavailableRetryStrategy.retryRequest will NOT be called, if there was an IO error like timeout, port not open or connection closed. In such cases, only HttpRequestRetryHandler.retryRequest will be called, and the retry will happen either immediately or after a fixed delay (I could not finally clarify this). So oleg's answer is actually the right one. There is no way to do it with support of HttpClient 4.5.
(I would actually like to call this a design bug, as delayed retries after an IO error are vitally important in a modern microservice environment.)
BackoffManager
/ ConnectionBackoffStrategy
combo can be used to dynamically increase or decrease max connection per route limits based on rate of I/O errors and 503 responses. They have no influence on request execution and cannot be used to control request re-execution
This is the best one can do with HC 4.x APIs
CloseableHttpClient client = HttpClientBuilder.create()
.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
return executionCount <= maxRetries &&
exception instanceof SocketException;
}
})
.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
return executionCount <= maxRetries &&
response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
}
@Override
public long getRetryInterval() {
return 100;
}
})
.build();
Please note there is presently no elegant way of enforcing a delay between request execution attempts in case of an I/O error or dynamically adjusting the retry interval based on request route.
You can use lambda
client.setRetryHandler((e, execCount, httpContext) -> {
if (execCount > tries) {
return false;
} else {
try {
Thread.sleep(recalMillis);
} catch (InterruptedException ex) {
//ignore
}
return true;
}
Notice that handler works only for IOExceptions types
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With