Spring Webclient not able to create connections

593 views Asked by At

I'm using Spring Webclient in a Spring Boot project to call a remote API

I've observed a strange behaviour with Webclient. Whenever the Remote API timeouts increase, Webclient goes into a state with very few active connections (less than 5, even though maxConnections is set in the config as 3200), and all the incoming connections get added to the Pending Queue, due to which after a while almost all requests are rejected with a PoolAcquirePendingLimitException exception.

The expected behaviour is that Webclient should create new connections (max upto 3200) to handle the incoming traffic

Webclient Config is as follows:

    @Bean
    public WebClient webClient(WebClient.Builder builder)
    {
        TcpClient tcpClient = TcpClient.create(getConnectionProvider())
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
                .wiretap(true)
                .doOnConnected(connection ->
                        connection.addHandlerLast(new ReadTimeoutHandler(10000, TimeUnit.MILLISECONDS)));
        ClientHttpConnector connector = new ReactorClientHttpConnector(HttpClient.from(tcpClient));
        return builder.uriBuilderFactory(initUriTemplateHandler())
                .clientConnector(connector)
                .build();
    }

    private ConnectionProvider getConnectionProvider()
    {
        return ConnectionProvider.builder("fixed")
                .maxConnections(3200)
                .pendingAcquireTimeout(Duration.ofMillis(10000))
                .pendingAcquireMaxCount(10000)
                .maxIdleTime(Duration.ofMinutes(10))
                .metrics(true)
                .build();
    }

    private DefaultUriBuilderFactory initUriTemplateHandler()
    {
        DefaultUriBuilderFactory uriFactory = new DefaultUriBuilderFactory();
        uriFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
        return uriFactory;
    }

This is how I'm making the API calls

T response = webClient.get()
                    .uri(url)
                    .retrieve()
                    .bodyToMono(responseClass)
                    .timeout(Duration.ofMillis(requestTimeout)) // varies between 15-20ms
                    .block();

enter image description here Below is a screenshot of the metrics[![enter image description here][2]][2]

This is a very high traffic application, and hence virtually it feels like the Pending Queue is stuck at 10000

Dependency Versions:

  1. spring-boot-starter-webflux: 2.2.4.RELEASE
  2. reactory-netty: 0.9.5.RELEASE
0

There are 0 answers