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

Reply via email to