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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值