Reputation: 4524
When Apache HTTP Client fails to connect to a server (IOException
) it may try to retryconnecting. However, it does not wait until retrying next time. This seems counterintuive, for instance when the target server is recovering or getting up, it may need some time to become ready for new requests.
Why is it so?
Here's a corresponding code from DefaultRequestDirector
:
for (;;) {
context.setAttribute(ExecutionContext.HTTP_REQUEST, wrapper);
// Increment connect count
connectCount++;
try {
if (!managedConn.isOpen()) {
managedConn.open(route, context, params);
} else {
managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params));
}
establishRoute(route, context);
break;
} catch (final IOException ex) {
try {
managedConn.close();
} catch (final IOException ignore) {
}
if (retryHandler.retryRequest(ex, connectCount, context)) {
...
} else {
throw ex;
}
}
}
Upvotes: 1
Views: 1064
Reputation: 797
DefaultRequestDirector
indeed has this hard-coded logic of intentionally ignoring IOException
. However, this API was deprecated in 4.3 and at 4.3+ you can directly set a RetryHandler to the HttpClientBuilder.
You will need to override the DefaultHttpRequestRetryHandler
that also ignores ConnectionException
, but in a more configurable way, by defining a list of non-retriable-classes (unfortunately, this constructor is protected, so a subclass needs to be created to expose that constructor).
CustomHttpRequestRetryHandler myRetryHandler = new CustomHttpRequestRetryHandler(3, false,
Collections.<Class<? extends IOException>>emptyList());
CloseableHttpClient client = HttpClients.custom()
.setRetryHandler(myRetryHandler)
.build();
private static class CustomHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
public CustomHttpRequestRetryHandler(int retryCount, boolean requestSentRetryEnabled, Collection<Class<? extends IOException>> clazzes) {
super(retryCount, requestSentRetryEnabled, clazzes);
}
}
good luck!
Upvotes: 1