0

I have an API Gateway server written with Sprint Boot 3 and Spring Cloud Gateway MVC (Spring Cloud 2024.0.1). I am using Eureka for API Discovery (spring-cloud-starter-netflix-eureka-client), which brings in Apache HTTP Client 4 & 5.

The routes are configured:

@Bean
public RouterFunction<ServerResponse> sampleRoute() {
    return RouterFunctions
        .route()
        .route(GatewayRequestPredicates.path("/sample-api/a-service/**"), HandlerFunctions.http())
        .before(BeforeFilterFunctions.routeId("sample-route"))
        .before(BeforeFilterFunctions.stripPrefix(2)) // remove "/sample-api/a-service/"
        .filter(RetryFilterFunctions.retry((r) -> r.setRetries(3).setMethods(Set.of(HttpMethod.GET, HttpMethod.OPTIONS, HttpMethod.HEAD))))
        .filter(LoadBalancerFilterFunctions.lb("A-SERVICE"))
        .filter(CircuitBreakerFilterFunctions.circuitBreaker("aServiceCircuitBreaker"))
        .build();
}

This has been working fine until we began testing the gateway under load. Unfortunately under load I am seeing the gateway hang as it exhausts all available HTTP connections for multiple routes. We see the following in the logs when the gateway becomes overwhelmed:

DEBUG org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager.get-ex-0000376182 endpoint leased [route: {}->[http://example.org:9080]][total available: 9; route allocated: 5 of 5; total allocated: 20 of 25]

The values of 5 max connections per route and 25 total max connections match the defaults on org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager.

How do I override these default max connection settings so that I can increase the max connections overall and the max connections per route?

1 Answer 1

0

The following code customizes the number of HTTP connections when using Apache HTTP client 5 with Spring Cloud Gateway:

@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
    // increase the size of the http connection pool for the API gateway routes
    return PoolingHttpClientConnectionManagerBuilder.create().setMaxConnTotal(400).setMaxConnPerRoute(20).build();
}

@Bean
public ClientHttpRequestFactory gatewayHttpClientFactory(final PoolingHttpClientConnectionManager poolingHttpClientConnectionManager) {
    // configure http client used for API gateway calls
    CloseableHttpClient httpClient = HttpClients
        .custom()
        .setConnectionManager(poolingHttpClientConnectionManager)
        .evictExpiredConnections()
        .evictIdleConnections(TimeValue.of(2L, TimeUnit.MINUTES))
        .build();
    return new HttpComponentsClientHttpRequestFactory(httpClient);
}

Interestingly, this changed the pool for the gateway routes, but not for the Eureka server communication. That must use another HTTP connection pool with the defaults (5/25).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.