4

That's my code:

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)

I call this function from multiple threads at the same time. When I only call it around 20~30 times in a single run it works perfectly fine. But when I call it 500~600 times in around 2 minutes (to the same URL) it throws

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

EDIT

I've tried creating only one instance of WebClient but it still throws the same exception

AvielNiego
  • 1,193
  • 2
  • 12
  • 27

3 Answers3

5

I found out this is happening due to this issue https://github.com/reactor/reactor-netty/issues/413

To resolve it you need to create WebClient like that:

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

you can change the pool size by calling PoolResources.fixed with its second parameter

Another solution is to replace this Async http client with another one like this one https://github.com/AsyncHttpClient/async-http-client

AvielNiego
  • 1,193
  • 2
  • 12
  • 27
  • We are using async-http-client (through the Play framework) and we still get the exception. But we are using nginx as a reverse proxy doing SSL termination. I think the issue still comes up with sufficient load. – dmz73 Nov 07 '18 at 10:17
  • 1
    Is it fixed by now? After heavy load with newest release of spring webflux (5.1.7) I got the same exception with huuuge stacktrace. – Michał Stochmal Jun 11 '19 at 07:31
  • I don't think this is fixed. I see this all the time on spring webflux 5.3.4. – Krum Mar 12 '21 at 14:18
1

Calling WebClient.create() repeatedly creates and initializes HTTP resources multiple times.

Without more details about this particular issue or a complete stacktrace, it's hard to pinpoint the exact problem here. But I suspect that creating a client HTTP connector for each call is wasteful and might cause issues with setting up SSL on the client side.

You could try instead:

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

If you're using Spring Boot, you should instead inject a WebClient.Builder instance and use it to create a WebClient instance.

Brian Clozel
  • 56,583
  • 15
  • 167
  • 176
0

I've been having the same issue, like the OP mentioned it happens under load but also it is easily triggered by an "nginx -s reload" while the server is under load. I posted this on the nginx forum but had no replies so far 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 comment applies.

dmz73
  • 1,588
  • 4
  • 20
  • 32