From b99d8c0764d5695ef78b7d39615cb6073ecf572d Mon Sep 17 00:00:00 2001 From: Hamado Dene Date: Fri, 5 May 2023 13:29:02 +0200 Subject: [PATCH] Introduce maxLifeTime for connection pool --- .../carapaceproxy/api/ConnectionPoolsResource.java | 3 +++ .../org/carapaceproxy/core/HttpProxyServer.java | 1 + .../carapaceproxy/core/ProxyRequestsManager.java | 1 + .../core/RuntimeServerConfiguration.java | 10 ++++++++++ .../server/config/ConnectionPoolConfiguration.java | 1 + .../carapaceproxy/backends/ConnectionPoolTest.java | 14 +++++++------- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/carapace-server/src/main/java/org/carapaceproxy/api/ConnectionPoolsResource.java b/carapace-server/src/main/java/org/carapaceproxy/api/ConnectionPoolsResource.java index 4f28b5c87..3683546f6 100644 --- a/carapace-server/src/main/java/org/carapaceproxy/api/ConnectionPoolsResource.java +++ b/carapace-server/src/main/java/org/carapaceproxy/api/ConnectionPoolsResource.java @@ -59,6 +59,7 @@ public static final class ConnectionPoolBean { private int connectTimeout; private int stuckRequestTimeout; private int idleTimeout; + private int maxLifeTime; private int disposeTimeout; private int keepaliveIdle; private int keepaliveInterval; @@ -92,6 +93,7 @@ public Map getAll() { conf.getConnectTimeout(), conf.getStuckRequestTimeout(), conf.getIdleTimeout(), + conf.getMaxLifeTime(), conf.getDisposeTimeout(), conf.getKeepaliveIdle(), conf.getKeepaliveInterval(), @@ -114,6 +116,7 @@ public Map getAll() { defaultConnectionPool.getConnectTimeout(), defaultConnectionPool.getStuckRequestTimeout(), defaultConnectionPool.getIdleTimeout(), + defaultConnectionPool.getMaxLifeTime(), defaultConnectionPool.getDisposeTimeout(), defaultConnectionPool.getKeepaliveIdle(), defaultConnectionPool.getKeepaliveInterval(), diff --git a/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java b/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java index 272c0dd31..89d374e5f 100644 --- a/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java +++ b/carapace-server/src/main/java/org/carapaceproxy/core/HttpProxyServer.java @@ -776,6 +776,7 @@ private boolean isConnectionsConfigurationChanged(RuntimeServerConfiguration new || newConfiguration.getConnectTimeout() != currentConfiguration.getConnectTimeout() || newConfiguration.getStuckRequestTimeout() != currentConfiguration.getStuckRequestTimeout() || newConfiguration.getIdleTimeout() != currentConfiguration.getIdleTimeout() + || newConfiguration.getMaxLifeTime() != currentConfiguration.getMaxLifeTime() || !newConfiguration.getConnectionPools().equals(currentConfiguration.getConnectionPools()); } diff --git a/carapace-server/src/main/java/org/carapaceproxy/core/ProxyRequestsManager.java b/carapace-server/src/main/java/org/carapaceproxy/core/ProxyRequestsManager.java index a974b9621..a9febb6e1 100644 --- a/carapace-server/src/main/java/org/carapaceproxy/core/ProxyRequestsManager.java +++ b/carapace-server/src/main/java/org/carapaceproxy/core/ProxyRequestsManager.java @@ -571,6 +571,7 @@ public void reloadConfiguration(RuntimeServerConfiguration newConfiguration, Col spec.maxConnections(connectionPool.getMaxConnectionsPerEndpoint()); spec.pendingAcquireTimeout(Duration.ofMillis(connectionPool.getBorrowTimeout())); spec.maxIdleTime(Duration.ofMillis(connectionPool.getIdleTimeout())); + spec.maxLifeTime(Duration.ofMillis(connectionPool.getMaxLifeTime())); spec.evictInBackground(Duration.ofMillis(connectionPool.getIdleTimeout() * 2)); spec.metrics(true); spec.lifo(); diff --git a/carapace-server/src/main/java/org/carapaceproxy/core/RuntimeServerConfiguration.java b/carapace-server/src/main/java/org/carapaceproxy/core/RuntimeServerConfiguration.java index 82ff82c6e..1709fe14a 100644 --- a/carapace-server/src/main/java/org/carapaceproxy/core/RuntimeServerConfiguration.java +++ b/carapace-server/src/main/java/org/carapaceproxy/core/RuntimeServerConfiguration.java @@ -64,6 +64,7 @@ public class RuntimeServerConfiguration { private int maxConnectionsPerEndpoint = 10; private int idleTimeout = 60_000; + private int maxLifeTime = idleTimeout * 2; private int stuckRequestTimeout = 120_000; private boolean backendsUnreachableOnStuckRequests = false; private int connectTimeout = 10_000; @@ -120,6 +121,7 @@ public RuntimeServerConfiguration() { connectTimeout, stuckRequestTimeout, idleTimeout, + maxLifeTime, disposeTimeout, keepaliveIdle, keepaliveInterval, @@ -136,6 +138,10 @@ public void configure(ConfigurationStore properties) throws ConfigurationNotVali if (this.idleTimeout <= 0) { throw new ConfigurationNotValidException("Invalid value '" + this.idleTimeout + "' for connectionsmanager.idletimeout"); } + this.maxLifeTime = properties.getInt("connectionsmanager.maxlifetime", maxLifeTime); + if (this.maxLifeTime <= 0) { + throw new ConfigurationNotValidException("Invalid value '" + this.maxLifeTime + "' for connectionsmanager.maxlifetime"); + } this.stuckRequestTimeout = properties.getInt("connectionsmanager.stuckrequesttimeout", stuckRequestTimeout); this.backendsUnreachableOnStuckRequests = properties.getBoolean("connectionsmanager.backendsunreachableonstuckrequests", backendsUnreachableOnStuckRequests); this.connectTimeout = properties.getInt("connectionsmanager.connecttimeout", connectTimeout); @@ -146,6 +152,7 @@ public void configure(ConfigurationStore properties) throws ConfigurationNotVali this.keepaliveCount = properties.getInt("connectionsmanager.keepalivecount", keepaliveCount); LOG.log(Level.INFO, "connectionsmanager.maxconnectionsperendpoint={0}", maxConnectionsPerEndpoint); LOG.log(Level.INFO, "connectionsmanager.idletimeout={0}", idleTimeout); + LOG.log(Level.INFO, "connectionsmanager.maxlifetime={0}", maxLifeTime); LOG.log(Level.INFO, "connectionsmanager.stuckrequesttimeout={0}", stuckRequestTimeout); LOG.log(Level.INFO, "connectionsmanager.backendsunreachableonstuckrequests={0}", backendsUnreachableOnStuckRequests); LOG.log(Level.INFO, "connectionsmanager.connecttimeout={0}", connectTimeout); @@ -354,6 +361,7 @@ private void configureConnectionPools(ConfigurationStore properties) throws Conf int connecttimeout = properties.getInt(prefix + "connecttimeout", connectTimeout); int stuckrequesttimeout = properties.getInt(prefix + "stuckrequesttimeout", stuckRequestTimeout); int idletimeout = properties.getInt(prefix + "idletimeout", idleTimeout); + int maxlifetime = properties.getInt(prefix + "maxlifetime", maxLifeTime); int disposetimeout = properties.getInt(prefix + "disposetimeout", disposeTimeout); int keepaliveidle = properties.getInt(prefix + "keepaliveidle", keepaliveIdle); int keepaliveinterval = properties.getInt(prefix + "keepaliveinterval", keepaliveInterval); @@ -368,6 +376,7 @@ private void configureConnectionPools(ConfigurationStore properties) throws Conf connecttimeout, stuckrequesttimeout, idletimeout, + maxlifetime, disposetimeout, keepaliveidle, keepaliveinterval, @@ -387,6 +396,7 @@ private void configureConnectionPools(ConfigurationStore properties) throws Conf getConnectTimeout(), getStuckRequestTimeout(), getIdleTimeout(), + getMaxLifeTime(), getDisposeTimeout(), getKeepaliveIdle(), getKeepaliveInterval(), diff --git a/carapace-server/src/main/java/org/carapaceproxy/server/config/ConnectionPoolConfiguration.java b/carapace-server/src/main/java/org/carapaceproxy/server/config/ConnectionPoolConfiguration.java index 82319d18c..64c52dccb 100644 --- a/carapace-server/src/main/java/org/carapaceproxy/server/config/ConnectionPoolConfiguration.java +++ b/carapace-server/src/main/java/org/carapaceproxy/server/config/ConnectionPoolConfiguration.java @@ -36,6 +36,7 @@ public class ConnectionPoolConfiguration { private int connectTimeout; private int stuckRequestTimeout; private int idleTimeout; + private int maxLifeTime; private int disposeTimeout; private int keepaliveIdle; private int keepaliveInterval; diff --git a/carapace-server/src/test/java/org/carapaceproxy/backends/ConnectionPoolTest.java b/carapace-server/src/test/java/org/carapaceproxy/backends/ConnectionPoolTest.java index 4012b0cff..f0358d622 100644 --- a/carapace-server/src/test/java/org/carapaceproxy/backends/ConnectionPoolTest.java +++ b/carapace-server/src/test/java/org/carapaceproxy/backends/ConnectionPoolTest.java @@ -165,7 +165,7 @@ public void test() throws Exception { // default pool ConnectionPoolConfiguration defaultPool = new ConnectionPoolConfiguration( - "*", "*", 10, 5_000, 10_000, 15_000, 20_000, 50_000, 500, 50, 5, true,true + "*", "*", 10, 5_000, 10_000, 15_000, 20_000, 40_000, 50_000, 500, 50, 5, true,true ); { ConnectionProvider provider = connectionPools.get(defaultPool); @@ -177,7 +177,7 @@ public void test() throws Exception { // pool with defaults ConnectionPoolConfiguration poolWithDefaults = new ConnectionPoolConfiguration( - "localhost", "localhost", 10, 5_000, 10_000, 15_000, 20_000, 50_000, 500, 50, 5, true, true + "localhost", "localhost", 10, 5_000, 10_000, 15_000, 20_000, 40_000, 50_000, 500, 50, 5, true, true ); { ConnectionProvider provider = connectionPools.get(poolWithDefaults); @@ -189,7 +189,7 @@ public void test() throws Exception { // custom pool ConnectionPoolConfiguration customPool = new ConnectionPoolConfiguration( - "localhosts", "localhost[0-9]", 20, 21_000, 22_000, 23_000, 24_000, 25_000, 250, 25, 2, true,true + "localhosts", "localhost[0-9]", 20, 21_000, 22_000, 23_000, 24_000, 40_000, 25_000, 250, 25, 2, true,true ); { ConnectionProvider provider = connectionPools.get(customPool); @@ -294,22 +294,22 @@ public void testAPIResource() throws Exception { // default pool assertThat(pools.get("*"), is(new ConnectionPoolsResource.ConnectionPoolBean( - "*", "*", 10, 5_000, 10_000, 15_000, 20_000, 50_000, 500, 50, 5, true,true, 0 + "*", "*", 10, 5_000, 10_000, 15_000, 20_000, 40_000, 50_000, 500, 50, 5, true,true, 0 ))); // pool with defaults assertThat(pools.get("localhost"), is(new ConnectionPoolsResource.ConnectionPoolBean( - "localhost", "localhost", 10, 5_000, 10_000, 15_000, 20_000, 50_000, 500, 50, 5, true,true, 1 + "localhost", "localhost", 10, 5_000, 10_000, 15_000, 20_000, 40_000,50_000, 500, 50, 5, true,true, 1 ))); // disabled custom pool assertThat(pools.get("localhost2"), is(new ConnectionPoolsResource.ConnectionPoolBean( - "localhost2", "localhost2", 10, 5_000, 10_000, 15_000, 20_000, 50_000, 500, 50, 5, true, false, 0 + "localhost2", "localhost2", 10, 5_000, 10_000, 15_000, 20_000, 40_000, 50_000, 500, 50, 5, true, false, 0 ))); // custom pool assertThat(pools.get("localhosts"), is(new ConnectionPoolsResource.ConnectionPoolBean( - "localhosts", "localhost[0-9]", 20, 21_000, 22_000, 23_000, 24_000, 25_000, 250, 25, 2, true, true, 0 + "localhosts", "localhost[0-9]", 20, 21_000, 22_000, 23_000, 24_000, 40_000, 25_000, 250, 25, 2, true, true, 0 ))); } }