httpClient 高级用法——retryHandler

Andy 2023年01月03日 518次浏览

RPC 框架层出不穷,但是说起鼻祖那一定是来自于 apache 的 httpClient。

RPC 框架的一个重要特征就是要解决因网络失败导致超时问题,换句话说就是要支持重试机制。httpClient 也不例外。

httpClient 是通过 retryHandler 来实现重试的。当请求过程出现异常时,你可以选择是否自动重试。

下面就看下具体使用步骤:

一. 定义 retryHandler
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

public boolean retryRequest(
        IOException exception,
        int executionCount,
        HttpContext context) {
    System.out.println(Thread.currentThread().getName()+ " try request: " + executionCount);
    if (executionCount >= 5) {
        // Do not retry if over max retry count
        return false;
    }
    if (exception instanceof InterruptedIOException) {
        // Timeout
        return false;
    }
    if (exception instanceof UnknownHostException) {
        // Unknown host, 通常不用重试,这里暂时返回 true 测试使用
        return true;
    }
    if (exception instanceof ConnectTimeoutException) {
        // Connection refused
        return false;
    }
    if (exception instanceof SSLException) {
        // SSL handshake exception
        return false;
    }
    HttpClientContext clientContext = HttpClientContext.adapt(context);
    HttpRequest request = clientContext.getRequest();
    boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
    if (idempotent) {
        // Retry if the request is considered idempotent
        return true;
    }
    return false;
}

};

二. 创建 httpClient,并添加 retryHandler
// 助力这里使用的是 CloseableHttpClient
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(myRetryHandler)
.build();
三. 测试
public static void main(String... args) throws IOException {

    try { 
        // 故意写错主机名测试
        HttpGet httpget = new HttpGet("http://localhosts:8080");
        System.out.println("Executing request " + httpget.getRequestLine());
        httpclient.execute(httpget);
        System.out.println("Request finished");
    } catch (IOException e) {
      //  throw e;
    } finally {
      
    }
}

四. 总结:

  1. 无论使用过程异常是否捕捉处理,都会重试;

  2. 达到最大重试次数后会将异常抛出,执行线程退出。