This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 716f0e513d fix(httpclient): bound the default connection pool (#7162)
716f0e513d is described below
commit 716f0e513d3ba69e341cbbc5130b9653ad6d382a
Author: Liming Deng <[email protected]>
AuthorDate: Wed Sep 30 09:58:42 2026 +0800
fix(httpclient): bound the default connection pool (#7162)
* fix(httpclient): bound the default connection pool
* fix(httpclient): bound pending connection acquisitions
---------
Co-authored-by: aias00 <[email protected]>
---
RELEASE-NOTES.md | 6 ++++++
.../httpclient/config/HttpClientProperties.java | 10 +++++-----
.../httpclient/HttpClientPropertiesTest.java | 2 ++
.../plugin/httpclient/HttpClientFactory.java | 3 +--
.../HttpClientPluginConfigurationTest.java | 22 ++++++++++++++++++++--
5 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 94d8aae441..9b9e5eb010 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -1,3 +1,9 @@
+## Unreleased
+
+### Behavior Changes
+
+1. The HTTP client now defaults to a fixed connection pool. Connection
acquisition waits up to 3 seconds, and Reactor Netty bounds pending
acquisitions to twice the configured maximum connection count. Set
`shenyu.httpclient.pool.type=ELASTIC` to retain the previous unbounded behavior.
+
## [v2.7.0]- 2024-12-23
### ✨ New Features
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/HttpClientProperties.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/HttpClientProperties.java
index caaf74a965..f0a9cac2ca 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/HttpClientProperties.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/main/java/org/apache/shenyu/plugin/httpclient/config/HttpClientProperties.java
@@ -396,12 +396,12 @@ public class HttpClientProperties {
public static class Pool {
/**
- * Type of pool for HttpClient to use, defaults to ELASTIC.
+ * Type of pool for HttpClient to use, defaults to FIXED.
*/
- private PoolType type = PoolType.ELASTIC;
+ private PoolType type = PoolType.FIXED;
/**
- * The channel pool map name, defaults to proxy.
+ * The channel pool map name, defaults to shenyu-proxy.
*/
private String name = "shenyu-proxy";
@@ -412,9 +412,9 @@ public class HttpClientProperties {
private Integer maxConnections =
ConnectionProvider.DEFAULT_POOL_MAX_CONNECTIONS;
/**
- * Only for type FIXED, the maximum time in millis to wait for
aquiring.
+ * Only for type FIXED, the maximum time in millis to wait for
acquiring, defaults to 3 seconds.
*/
- private Long acquireTimeout =
ConnectionProvider.DEFAULT_POOL_ACQUIRE_TIMEOUT;
+ private Long acquireTimeout = 3000L;
/**
* Time in millis after which the channel will be closed,
diff --git
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/HttpClientPropertiesTest.java
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/HttpClientPropertiesTest.java
index d2a5f7c164..90ee5a9cd1 100644
---
a/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/HttpClientPropertiesTest.java
+++
b/shenyu-plugin/shenyu-plugin-httpclient/src/test/java/org/apache/shenyu/plugin/httpclient/HttpClientPropertiesTest.java
@@ -123,6 +123,8 @@ public class HttpClientPropertiesTest {
public void httpClientPropertiesPoolTest() {
HttpClientProperties httpClientProperties = new HttpClientProperties();
HttpClientProperties.Pool pool = httpClientProperties.getPool();
+ Assertions.assertEquals(HttpClientProperties.Pool.PoolType.FIXED,
pool.getType());
+ Assertions.assertEquals(3000L, pool.getAcquireTimeout());
pool.setAcquireTimeout(ConnectionProvider.DEFAULT_POOL_ACQUIRE_TIMEOUT);
pool.setMaxConnections(ConnectionProvider.DEFAULT_POOL_MAX_CONNECTIONS);
pool.setName("name");
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientFactory.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientFactory.java
index 44ac56a8fc..d8911dfe24 100644
---
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientFactory.java
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/main/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientFactory.java
@@ -180,8 +180,7 @@ public class HttpClientFactory extends
AbstractFactoryBean<HttpClient> {
throw new IllegalArgumentException("Acquire Timeout value must be
positive");
}
builder.maxConnections(pool.getMaxConnections())
-
.pendingAcquireTimeout(Duration.ofMillis(pool.getAcquireTimeout()))
- .pendingAcquireMaxCount(-1);
+
.pendingAcquireTimeout(Duration.ofMillis(pool.getAcquireTimeout()));
}
/**
diff --git
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/test/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfigurationTest.java
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/test/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfigurationTest.java
index f2d852c20a..c184a79d6d 100644
---
a/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/test/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfigurationTest.java
+++
b/shenyu-spring-boot-starter/shenyu-spring-boot-starter-plugin/shenyu-spring-boot-starter-plugin-httpclient/src/test/java/org/apache/shenyu/springboot/starter/plugin/httpclient/HttpClientPluginConfigurationTest.java
@@ -20,6 +20,10 @@ package
org.apache.shenyu.springboot.starter.plugin.httpclient;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import java.time.Duration;
@@ -27,6 +31,7 @@ import org.apache.shenyu.plugin.api.ShenyuPlugin;
import org.apache.shenyu.plugin.httpclient.config.HttpClientProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.Answers;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import
org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -35,6 +40,7 @@ import org.springframework.context.annotation.Configuration;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
+import reactor.netty.resources.ConnectionProvider.Builder;
/**
* Test case for {@link HttpClientPluginConfiguration}.
@@ -60,7 +66,6 @@ public class HttpClientPluginConfigurationTest {
"debug=true",
"shenyu.httpclient.connectTimeout=3",
"shenyu.httpclient.responseTimeout=0",
- "shenyu.httpclient.pool.PoolType=0",
"shenyu.httpclient.pool.name=proxy",
"shenyu.httpclient.pool.maxConnections=1",
"shenyu.httpclient.pool.acquireTimeout=45000",
@@ -79,7 +84,7 @@ public class HttpClientPluginConfigurationTest {
assertNotNull(properties);
assertThat(properties.getConnectTimeout(), is(3));
assertThat(properties.getResponseTimeout(),
is(Duration.ZERO));
- assertThat(properties.getPool().getType(),
is(HttpClientProperties.Pool.PoolType.ELASTIC));
+ assertThat(properties.getPool().getType(),
is(HttpClientProperties.Pool.PoolType.FIXED));
assertThat(properties.getPool().getName(), is("proxy"));
assertThat(properties.getPool().getMaxConnections(),
is(1));
assertThat(properties.getPool().getAcquireTimeout(),
is(ConnectionProvider.DEFAULT_POOL_ACQUIRE_TIMEOUT));
@@ -95,6 +100,19 @@ public class HttpClientPluginConfigurationTest {
});
}
+ @Test
+ public void testFixedConnectionPoolUsesBoundedPendingQueue() {
+ HttpClientProperties.Pool pool = new HttpClientProperties.Pool();
+ Builder builder = mock(Builder.class, Answers.RETURNS_SELF);
+ HttpClientFactory factory = new HttpClientFactory(new
HttpClientProperties(), null, new ServerProperties());
+
+ factory.buildFixedConnectionPool(pool, builder);
+
+
verify(builder).maxConnections(ConnectionProvider.DEFAULT_POOL_MAX_CONNECTIONS);
+ verify(builder).pendingAcquireTimeout(Duration.ofMillis(3000L));
+ verify(builder, never()).pendingAcquireMaxCount(anyInt());
+ }
+
@Test
public void testHttpClient() {
applicationContextRunner