使用httpClient的过程中,如果没有设置自定义的 retryHandler,系统会使用默认的
DefaultHttpRequestRetryHandler.INSTANCE;
public DefaultHttpRequestRetryHandler() {
this(3, false);
}
public DefaultHttpRequestRetryHandler(final int retryCount, final boolean requestSentRetryEnabled) {
this(retryCount, requestSentRetryEnabled, Arrays.asList(
InterruptedIOException.class,
UnknownHostException.class,
ConnectException.class,
SSLException.class));
}
protected DefaultHttpRequestRetryHandler(
final int retryCount,
final boolean requestSentRetryEnabled,
final Collection<Class<? extends IOException>> clazzes) {
super();
this.retryCount = retryCount;
this.requestSentRetryEnabled = requestSentRetryEnabled;
this.nonRetriableClasses = new HashSet<Class<? extends IOException>>();
for (final Class<? extends IOException> clazz: clazzes) {
this.nonRetriableClasses.add(clazz);
}
}
可以看到,默认是超时3次,而且有一个属性 nonRetriableClasses ,标记了 遇到这种class类型,不会去重走 retry 逻辑,源码如下:
@Override
public boolean retryRequest(
final IOException exception,
final int executionCount,
final HttpContext context) {
Args.notNull(exception, "Exception parameter");
Args.notNull(context, "HTTP context");
if (executionCount > this.retryCount) {
// Do not retry if over max retry count
return false;
}
if (this.nonRetriableClasses.contains(exception.getClass())) {
return false;
} else {
for (final Class<? extends IOException> rejectException : this.nonRetriableClasses) {
if (rejectException.isInstance(exception)) {
return false;
}
}
}
可以看到,直接return false,不尝试触发重试逻辑;
这时候我们去看 3个超时配置 对应的异常,
connectTimeout
socketTimeout
connectionRequestTimeout
对应到是异常:
SocketTimeoutException
public class SocketTimeoutException extends java.io.InterruptedIOException {
很明显,这个异常是 InterruptedIOException 的子类,也就是默认的 retryHandler中忽略重试的 类型,所以默认情况下,超时类的异常不会触发重试逻辑,大家可以通过重写retryHandler来使其生效
CloseableHttpClient httpClient=HttpClients.custom().setDefaultRequestConfig(requestConfig).setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if(executionCount >= 5) {
logger.info("executionCount = " + executionCount);
return false;
}
return true;
}
}).build()