Spring WebClient 抛出 javax.net.ssl.SSLException:大量使用时 SSLEngine 已关闭

Spring WebClient throws javax.net.ssl.SSLException: SSLEngine closed already when used heavily

这是我的代码:

WebClient.create().post()
                .uri(URI.create(url))
                .header("Authorization",
                        "Basic " + Base64Utils.encodeToString(("username:password").getBytes(UTF_8)))
                .body(Mono.just(requestBody), Object.class)
                .retrieve()
                .bodyToMono(responseType)

我同时从多个线程调用这个函数。 当我在一个 运行 中只调用它大约 20~30 次时,它工作得很好。但是当我在大约 2 分钟内调用它 500~600 次时(对同一个 URL)它抛出

javax.net.ssl.SSLException: SSLEngine closed already
    at io.netty.handler.ssl.SslHandler.wrap(...)(Unknown Source)

编辑

我试过只创建一个 WebClient 的实例,但它仍然抛出相同的异常

多次调用WebClient.create()创建并初始化HTTP资源。

没有关于此特定问题的更多详细信息或完整的堆栈跟踪,很难在此处查明确切的问题。但我怀疑为每个调用创建一个客户端 HTTP 连接器是一种浪费,并且可能会导致在客户端设置 SSL 时出现问题。

您可以试试:

WebClient webClient = WebClient.create();
// then in your for loop
webClient.post() //...

如果您正在使用 Spring 启动,您应该注入一个 WebClient.Builder 实例并使用它来创建一个 WebClient 实例。

我一直遇到同样的问题,就像 OP 提到的那样,它发生在负载下,但也很容易在服务器负载下由 "nginx -s reload" 触发。我在 nginx 论坛上发布了这个,但到目前为止没有回复 https://forum.nginx.org/read.php?2,281786. In my case I am using a singleton client instance for the multiple requests, so I don't think Brian's 评论适用。

我发现这是由于这个问题而发生的 https://github.com/reactor/reactor-netty/issues/413

要解决它,您需要像这样创建 WebClient

WebClient webClient = WebClient.builder()
               .clientConnector(new ReactorClientHttpConnector(options -> {
                   options.poolResources(PoolResources.fixed("httpPool")).compression(true);
               })).build();

您可以通过调用 PoolResources.fixed 及其第二个参数

来更改池大小

另一种解决方案是将此 Async http 客户端替换为另一个类似的客户端 https://github.com/AsyncHttpClient/async-http-client