diff --git a/docs/modules/ROOT/partials/_configprops.adoc b/docs/modules/ROOT/partials/_configprops.adoc index cae75c8f17..fe6703e933 100644 --- a/docs/modules/ROOT/partials/_configprops.adoc +++ b/docs/modules/ROOT/partials/_configprops.adoc @@ -90,6 +90,7 @@ |spring.cloud.gateway.httpclient.pool.metrics | `+++false+++` | Enables channel pools metrics to be collected and registered in Micrometer. Disabled by default. |spring.cloud.gateway.httpclient.pool.name | `+++proxy+++` | The channel pool map name, defaults to proxy. |spring.cloud.gateway.httpclient.pool.type | `+++elastic+++` | Type of pool for HttpClient to use, defaults to ELASTIC. +|spring.cloud.gateway.httpclient.pool.leasingStrategy | `+++fifo+++` | Configures the leasing strategy for the pool, defaults to FIFO. |spring.cloud.gateway.httpclient.proxy.host | | Hostname for proxy configuration of Netty HttpClient. |spring.cloud.gateway.httpclient.proxy.non-proxy-hosts-pattern | | Regular expression (Java) for a configured list of hosts. that should be reached directly, bypassing the proxy |spring.cloud.gateway.httpclient.proxy.password | | Password for proxy configuration of Netty HttpClient. diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientFactory.java index b4fa7ffc1e..136de3b9e8 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientFactory.java @@ -33,6 +33,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool.LeasingStrategy.FIFO; import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool.PoolType.DISABLED; import static org.springframework.cloud.gateway.config.HttpClientProperties.Pool.PoolType.FIXED; @@ -189,6 +190,16 @@ protected ConnectionProvider buildConnectionProvider(HttpClientProperties proper } builder.evictInBackground(pool.getEvictionInterval()); builder.metrics(pool.isMetrics()); + + // Define the pool leasing strategy + if (pool.getLeasingStrategy() == FIFO) { + builder.fifo(); + } + else { + // LIFO + builder.lifo(); + } + connectionProvider = builder.build(); } return connectionProvider; 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 85b3b02759..c03b047346 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 @@ -208,6 +208,11 @@ public static class Pool { */ private boolean metrics = false; + /** + * Configures the leasing strategy for the pool, defaults to FIFO which is Netty's default. + */ + private LeasingStrategy leasingStrategy = LeasingStrategy.FIFO; + public PoolType getType() { return type; } @@ -272,11 +277,20 @@ public void setMetrics(boolean metrics) { this.metrics = metrics; } + public LeasingStrategy getLeasingStrategy() { + return leasingStrategy; + } + + public void setLeasingStrategy(LeasingStrategy leasingStrategy) { + this.leasingStrategy = leasingStrategy; + } + @Override public String toString() { return "Pool{" + "type=" + type + ", name='" + name + '\'' + ", maxConnections=" + maxConnections + ", acquireTimeout=" + acquireTimeout + ", maxIdleTime=" + maxIdleTime + ", maxLifeTime=" - + maxLifeTime + ", evictionInterval=" + evictionInterval + ", metrics=" + metrics + '}'; + + maxLifeTime + ", evictionInterval=" + evictionInterval + ", metrics=" + metrics + + ", leasingStrategy=" + leasingStrategy + '}'; } public enum PoolType { @@ -298,6 +312,20 @@ public enum PoolType { } + public enum LeasingStrategy { + + /** + * FIFO leasing strategy. + */ + FIFO, + + /** + * LIFO leasing strategy. + */ + LIFO + + } + } public static class Proxy { 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 50f5b197d6..570911f6af 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 @@ -52,6 +52,7 @@ import org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint; import org.springframework.cloud.gateway.actuate.GatewayLegacyControllerEndpoint; import org.springframework.cloud.gateway.config.GatewayAutoConfigurationTests.CustomHttpClientFactory.CustomSslConfigurer; +import org.springframework.cloud.gateway.config.HttpClientProperties.Pool.LeasingStrategy; import org.springframework.cloud.gateway.filter.factory.TokenRelayGatewayFilterFactory; import org.springframework.cloud.gateway.filter.headers.GRPCRequestHeadersFilter; import org.springframework.cloud.gateway.filter.headers.GRPCResponseHeadersFilter; @@ -119,6 +120,7 @@ public void nettyHttpClientConfigured() { "spring.cloud.gateway.httpclient.pool.eviction-interval=10s", "spring.cloud.gateway.httpclient.pool.type=fixed", "spring.cloud.gateway.httpclient.pool.metrics=true", + "spring.cloud.gateway.httpclient.pool.leasing-strategy=lifo", "spring.cloud.gateway.httpclient.compression=true", "spring.cloud.gateway.httpclient.wiretap=true", // greater than integer max value "spring.cloud.gateway.httpclient.max-initial-line-length=2147483647", @@ -133,6 +135,7 @@ public void nettyHttpClientConfigured() { assertThat(properties.isCompression()).isEqualTo(true); assertThat(properties.getPool().getEvictionInterval()).hasSeconds(10); assertThat(properties.getPool().isMetrics()).isEqualTo(true); + assertThat(properties.getPool().getLeasingStrategy()).isEqualTo(LeasingStrategy.LIFO); assertThat(httpClient.configuration().isAcceptGzip()).isTrue(); assertThat(httpClient.configuration().loggingHandler()).isNotNull();