HttpClient中 RetryHandler的理解与使用

Posted OkidoGreen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpClient中 RetryHandler的理解与使用相关的知识,希望对你有一定的参考价值。

使用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()

以上是关于HttpClient中 RetryHandler的理解与使用的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient的使用

HttpClient--使用HttpClient进行Get Post请求访问

轻松把玩HttpClient之封装HttpClient工具类,插件式配置HttpClient对象

轻松把玩HttpClient之封装HttpClient工具类(现有网上分享中的最强大的工具类)

处理注入的 HttpClient

C#中HttpClient使用注意:预热与长连接