实现HttpClient重试

来源:互联网 发布:守望先锋生涯数据出错 编辑:程序博客网 时间:2024/06/01 08:13

场景应用

目前程序中涉及到需要callback操作,product需要被动的接收consume的处理状态,为了最大程度的能够callback成功因此consume在http调用出现问题(如:服务不可用、异常、超时)情况下需要进行重试(retry request)。

1、针对异常的重试

例如:connect timed out/read timed out

HttpClientBuilder.create()                .setRetryHandler(new HttpRequestRetryHandler() {                    @Override                    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {                        if (executionCount >= 3) {                            // Do not retry if over max retry count                            return false;                        }                        return true;                    })                .setConnectionManager(new PoolingHttpClientConnectionManager())                .setDefaultRequestConfig(requestConfig)                .build();
如此实现针对异常进行3次重试的效果

2、针对响应错误码进行重试

例如400/500等

首先需要定义一个重试策略类:

package com.gomefinance.esign.httpretry;import org.apache.http.HttpResponse;import org.apache.http.client.ServiceUnavailableRetryStrategy;/** * 针对请求地址可达,非200 响应码进行重试 */public class MyServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy {    private int executionCount;    private long retryInterval;    MyServiceUnavailableRetryStrategy(Builder builder) {        this.executionCount = builder.executionCount;        this.retryInterval = builder.retryInterval;    }    /**     * retry逻辑     */    @Override    public boolean retryRequest(HttpResponse response, int executionCount, org.apache.http.protocol.HttpContext context) {        if (response.getStatusLine().getStatusCode() != 200 && executionCount < executionCount)            return true;        else            return false;    }    /**     * retry间隔时间     */    @Override    public long getRetryInterval() {        return this.retryInterval;    }    public static final class Builder {        private int executionCount;        private long retryInterval;        public Builder() {            executionCount = 3;            retryInterval = 1000;        }        public Builder executionCount(int executionCount) {            this.executionCount = executionCount;            return this;        }        public Builder retryInterval(long retryInterval) {            this.retryInterval = retryInterval;            return this;        }        public MyServiceUnavailableRetryStrategy build() {            return new MyServiceUnavailableRetryStrategy(this);        }    }}
之后需要如下
ServiceUnavailableRetryStrategy serviceUnavailableRetryStrategy = new MyServiceUnavailableRetryStrategy.Builder()                .executionCount(3)                .retryInterval(1000)                .build();HttpClientBuilder.create()                .setServiceUnavailableRetryStrategy(serviceUnavailableRetryStrategy)                .setConnectionManager(new PoolingHttpClientConnectionManager())                .setDefaultRequestConfig(requestConfig)                .build();
即可实现针对错误码的异常处理

3、针对错误和错误码进行处理

ServiceUnavailableRetryStrategy serviceUnavailableRetryStrategy = new MyServiceUnavailableRetryStrategy.Builder()                .executionCount(3)                .retryInterval(1000)                .build();        httpClient = HttpClientBuilder.create()                .setRetryHandler((e,executionCount,contr)->{                    if (executionCount >= 3) {                        // Do not retry if over max retry count                        return false;                    }                    return true;                })                .setServiceUnavailableRetryStrategy(serviceUnavailableRetryStrategy)                .setConnectionManager(new PoolingHttpClientConnectionManager())                .setDefaultRequestConfig(requestConfig)                .build();
以上就是针对HttpClient重试的方式。

参考文献

ranong项目总结-HttpClient-RetryHandler重试(一)