diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java index 0f636481..c39592c5 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.cloud.gateway.config; import java.security.cert.X509Certificate; +import java.time.Duration; import java.util.List; import java.util.Set; import java.util.function.Supplier; @@ -663,21 +664,7 @@ public class GatewayAutoConfiguration { List customizers) { // configure pool resources - HttpClientProperties.Pool pool = properties.getPool(); - - ConnectionProvider connectionProvider; - if (pool.getType() == DISABLED) { - connectionProvider = ConnectionProvider.newConnection(); - } - else if (pool.getType() == FIXED) { - connectionProvider = ConnectionProvider.fixed(pool.getName(), - pool.getMaxConnections(), pool.getAcquireTimeout(), - pool.getMaxIdleTime(), pool.getMaxLifeTime()); - } - else { - connectionProvider = ConnectionProvider.elastic(pool.getName(), - pool.getMaxIdleTime(), pool.getMaxLifeTime()); - } + ConnectionProvider connectionProvider = buildConnectionProvider(properties); HttpClient httpClient = HttpClient.create(connectionProvider) // TODO: move customizations to HttpClientCustomizers @@ -778,6 +765,42 @@ public class GatewayAutoConfiguration { return httpClient; } + private ConnectionProvider buildConnectionProvider( + HttpClientProperties properties) { + HttpClientProperties.Pool pool = properties.getPool(); + + ConnectionProvider connectionProvider; + if (pool.getType() == DISABLED) { + connectionProvider = ConnectionProvider.newConnection(); + } + else { + // create either Fixed or Elastic pool + ConnectionProvider.Builder builder = ConnectionProvider + .builder(pool.getName()); + if (pool.getType() == FIXED) { + builder.maxConnections(pool.getMaxConnections()) + .pendingAcquireMaxCount(-1).pendingAcquireTimeout( + Duration.ofMillis(pool.getAcquireTimeout())); + } + else { + // Elastic + builder.maxConnections(Integer.MAX_VALUE) + .pendingAcquireTimeout(Duration.ofMillis(0)) + .pendingAcquireMaxCount(-1); + } + + if (pool.getMaxIdleTime() != null) { + builder.maxIdleTime(pool.getMaxIdleTime()); + } + if (pool.getMaxLifeTime() != null) { + builder.maxLifeTime(pool.getMaxLifeTime()); + } + builder.evictInBackground(pool.getEvictionInterval()); + connectionProvider = builder.build(); + } + return connectionProvider; + } + @Bean public HttpClientProperties httpClientProperties() { return new HttpClientProperties(); diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java index a42b2a75..fba8a31e 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java @@ -211,6 +211,12 @@ public class HttpClientProperties { */ private Duration maxLifeTime = null; + /** + * Perform regular eviction checks in the background at a specified interval. + * Disabled by default ({@link Duration#ZERO}) + */ + private Duration evictionInterval = Duration.ZERO; + public PoolType getType() { return type; } @@ -259,12 +265,20 @@ public class HttpClientProperties { this.maxLifeTime = maxLifeTime; } + public Duration getEvictionInterval() { + return evictionInterval; + } + + public void setEvictionInterval(Duration evictionInterval) { + this.evictionInterval = evictionInterval; + } + @Override public String toString() { return "Pool{" + "type=" + type + ", name='" + name + '\'' + ", maxConnections=" + maxConnections + ", acquireTimeout=" + acquireTimeout + ", maxIdleTime=" + maxIdleTime + ", maxLifeTime=" - + maxLifeTime + '}'; + + maxLifeTime + ", evictionInterval=" + evictionInterval + '}'; } public enum PoolType { diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java index 3675d495..bf01efe6 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java @@ -94,6 +94,7 @@ public class GatewayAutoConfigurationTests { "spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager=true", "spring.cloud.gateway.httpclient.connect-timeout=10", "spring.cloud.gateway.httpclient.response-timeout=10s", + "spring.cloud.gateway.httpclient.pool.eviction-interval=10s", "spring.cloud.gateway.httpclient.pool.type=fixed", "spring.cloud.gateway.httpclient.compression=true", // greather than integer max value @@ -108,6 +109,7 @@ public class GatewayAutoConfigurationTests { assertThat(properties.getMaxInitialLineLength().toBytes()) .isLessThanOrEqualTo(Integer.MAX_VALUE); assertThat(properties.isCompression()).isEqualTo(true); + assertThat(properties.getPool().getEvictionInterval()).hasSeconds(10); /* * FIXME: 2.1.0 HttpClientOptions options = httpClient.options(); *