java 11 上的 SSL 通信期间发生 SocketException 时,如何使用 DefaultHttpRequestRetryHandler(HTTPClient) 重试?

Hir*_*oto 4 java httpclient apache-httpcomponents java-11

我应该如何实现它才能在 java11 上使用httpclient重试 SSL 通信?

如下所示覆盖 DefaultHttpRequestRetryHandler 是否更好?
有没有更好的办法?

  public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {

    @Override
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
      IOException cause = exception;
      if (exception instanceof SSLException) {
        if (exception.getCause() != null && exception.getCause() instanceof IOException) {
          cause = (IOException) exception.getCause();
        }
      }
      return super.retryRequest(cause, executionCount, context);
    }
  }
Run Code Online (Sandbox Code Playgroud)

在 Java 11 中,不会重试 SocketException,因为 SocketException 是用 SSLException 包装的。

我阅读了以下内容。

使用java11时,随机出现以下错误,概率小于0.01%。

if ((cause != null) && (cause instanceof IOException)) {
    ssle = new SSLException(reason);
} 
Run Code Online (Sandbox Code Playgroud)

Hir*_*oto 7

我做了 HttpRequestRetryHandler 类。

  public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {

    @Override
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
      IOException cause = exception;
      if (exception instanceof SSLException) {
        if (exception.getCause() != null && exception.getCause() instanceof IOException) {
          cause = (IOException) exception.getCause();
        }
      }
      return super.retryRequest(cause, executionCount, context);
    }
  }
Run Code Online (Sandbox Code Playgroud)

并将其设置为 HttpClientBuilder。

CloseableHttpClient httpclient = HttpClients.custom()
        .setRetryHandler(new HttpRequestRetryHandler())
        .build();
Run Code Online (Sandbox Code Playgroud)

结论

  • SSL 通信质量与使用 java8 时相同。
  • 服务器或网络的底层问题仍然存在,但java11的影响已经解决。

  • 请关注https://github.com/apache/httpcomponents-client/pull/178 (3认同)