本文主要研究一下HttpClient的ServiceUnavailableRetryStrategy
org/apache/http/client/ServiceUnavailableRetryStrategy.java
public interface ServiceUnavailableRetryStrategy {
/**
* Determines if a method should be retried given the response from the target server.
*
* @param response the response from the target server
* @param executionCount the number of times this method has been
* unsuccessfully executed
* @param context the context for the request execution
* @return {@code true} if the method should be retried, {@code false}
* otherwise
*/
boolean retryRequest(HttpResponse response, int executionCount, HttpContext context);
/**
* @return The interval between the subsequent auto-retries.
*/
long getRetryInterval();
}
ServiceUnavailableRetryStrategy定义了retryRequest方法用于返回是否该重试,getRetryInterval返回自动重试的间隔
org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java
@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class DefaultServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy {
/**
* Maximum number of allowed retries if the server responds with a HTTP code
* in our retry code list. Default value is 1.
*/
private final int maxRetries;
/**
* Retry interval between subsequent requests, in milliseconds. Default
* value is 1 second.
*/
private final long retryInterval;
public DefaultServiceUnavailableRetryStrategy(final int maxRetries, final int retryInterval) {
super();
Args.positive(maxRetries, "Max retries");
Args.positive(retryInterval, "Retry interval");
this.maxRetries = maxRetries;
this.retryInterval = retryInterval;
}
public DefaultServiceUnavailableRetryStrategy() {
this(1, 1000);
}
@Override
public boolean retryRequest(final HttpResponse response, final int executionCount, final HttpContext context) {
return executionCount <= maxRetries &&
response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
}
@Override
public long getRetryInterval() {
return retryInterval;
}
}
DefaultServiceUnavailableRetryStrategy实现了ServiceUnavailableRetryStrategy接口,其构造器接收maxRetries(
默认1
)及retryInterval(单位毫秒,默认1s
);retryRequest方法在executionCount小于等于maxRetries且statusCode=503的时候返回true
org/apache/http/impl/execchain/ServiceUnavailableRetryExec.java
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
public class ServiceUnavailableRetryExec implements ClientExecChain {
private final Log log = LogFactory.getLog(getClass());
private final ClientExecChain requestExecutor;
private final ServiceUnavailableRetryStrategy retryStrategy;
public ServiceUnavailableRetryExec(
final ClientExecChain requestExecutor,
final ServiceUnavailableRetryStrategy retryStrategy) {
super();
Args.notNull(requestExecutor, "HTTP request executor");
Args.notNull(retryStrategy, "Retry strategy");
this.requestExecutor = requestExecutor;
this.retryStrategy = retryStrategy;
}
@Override
public CloseableHttpResponse execute(
final HttpRoute route,
final HttpRequestWrapper request,
final HttpClientContext context,
final HttpExecutionAware execAware) throws IOException, HttpException {
final Header[] origheaders = request.getAllHeaders();
for (int c = 1;; c++) {
final CloseableHttpResponse response = this.requestExecutor.execute(
route, request, context, execAware);
try {
if (this.retryStrategy.retryRequest(response, c, context)
&& RequestEntityProxy.isRepeatable(request)) {
response.close();
final long nextInterval = this.retryStrategy.getRetryInterval();
if (nextInterval > 0) {
try {
this.log.trace("Wait for " + nextInterval);
Thread.sleep(nextInterval);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw new InterruptedIOException();
}
}
request.setHeaders(origheaders);
} else {
return response;
}
} catch (final RuntimeException ex) {
response.close();
throw ex;
}
}
}
}
ServiceUnavailableRetryExec实现了ClientExecChain接口,其execute方法执行完requestExecutor.execute之后,会请求retryStrategy.retryRequest判断是否需要重试,在需要重试且RequestEntityProxy.isRepeatable(request)时,获取retryStrategy.getRetryInterval()进行sleep,然后继续下个循环请求execute方法
HttpClient的ServiceUnavailableRetryStrategy定义了retryRequest方法用于返回是否该重试,getRetryInterval返回自动重试的间隔;DefaultServiceUnavailableRetryStrategy实现了ServiceUnavailableRetryStrategy接口,其构造器接收maxRetries(默认1
)及retryInterval(单位毫秒,默认1s
);retryRequest方法在executionCount小于等于maxRetries且statusCode=503的时候返回true;ServiceUnavailableRetryExec则使用ServiceUnavailableRetryStrategy完成了针对503的重试。