1. 程式人生 > >實現HttpClient重試

實現HttpClient重試

場景應用

目前程式中涉及到需要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重試(一)