当Apache HTTP Client无法连接到服务器(IOException
)时,它可能会尝试重新连接。但是,它不会等到下次重试。这似乎是违法的,例如当目标服务器正在恢复或起来时,可能需要一些时间来准备好新的请求。
为什么会这样?
以下是来自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;
}
}
}
答案 0 :(得分:0)
DefaultRequestDirector
确实有这种硬编码的逻辑故意忽略IOException
。但是,这个API在4.3和4.3+中已弃用,您可以直接将RetryHandler设置为HttpClientBuilder。
您需要覆盖DefaultHttpRequestRetryHandler
同样忽略ConnectionException
,但是以更可配置的方式,通过定义不可重试类的列表(不幸的是,这个构造函数受到保护,所以a需要创建子类来公开该构造函数)。
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);
}
}
祝你好运!