Skip to content

Commit f3b9c49

Browse files
committed
inbound: Restrict the HTTP/1 idle timeout (#1931)
The inbound proxy may hold idle inbound connections to the application open for (by default) 20s. This can be problematic when a server sets a lesser idle timeout and that idle timeout matches some poll interval (like a Kubernetes probe or metrics scrape). This change reduces the HTTP/1 connection pool idle timeout to 3s. This should be short enough to avoid this problem in many cases but it is also large enough that connection pooling can help busy services. In the future, this configuration should be made dynamic via the inbound policy API. Signed-off-by: Oliver Gould <[email protected]>
1 parent 88518a8 commit f3b9c49

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

linkerd/app/src/env.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ const ENV_INITIAL_STREAM_WINDOW_SIZE: &str = "LINKERD2_PROXY_HTTP2_INITIAL_STREA
218218
const ENV_INITIAL_CONNECTION_WINDOW_SIZE: &str =
219219
"LINKERD2_PROXY_HTTP2_INITIAL_CONNECTION_WINDOW_SIZE";
220220

221+
const ENV_INBOUND_HTTP1_CONNECTION_POOL_IDLE_TIMEOUT: &str =
222+
"LINKERD2_PROXY_INBOUND_HTTP1_CONNECTION_POOL_IDLE_TIMEOUT";
223+
221224
// Default values for various configuration fields
222225
const DEFAULT_OUTBOUND_LISTEN_ADDR: &str = "127.0.0.1:4140";
223226
pub const DEFAULT_INBOUND_LISTEN_ADDR: &str = "0.0.0.0:4143";
@@ -253,6 +256,13 @@ const DEFAULT_INITIAL_CONNECTION_WINDOW_SIZE: u32 = 1048576; // 1MB ~ 16 streams
253256
const DEFAULT_INBOUND_ROUTER_MAX_IDLE_AGE: Duration = Duration::from_secs(20);
254257
const DEFAULT_OUTBOUND_ROUTER_MAX_IDLE_AGE: Duration = Duration::from_secs(5);
255258

259+
// XXX This default inbound connection idle timeout should be less than or equal
260+
// to the server's idle timeout so that we don't try to reuse a connection as it
261+
// is being timed out of the server.
262+
//
263+
// In the future this should be made configurable per-server from the proxy API.
264+
const DEFAULT_INBOUND_HTTP1_CONNECTION_POOL_IDLE_TIMEOUT: Duration = Duration::from_secs(3);
265+
256266
// By default, we don't limit the number of connections a connection pol may
257267
// use, as doing so can severely impact CPU utilization for applications with
258268
// many concurrent requests. It's generally preferable to use the MAX_IDLE_AGE
@@ -495,6 +505,12 @@ pub fn parse_config<S: Strings>(strings: &S) -> Result<super::Config, EnvError>
495505
inbound_cache_max_idle_age?.unwrap_or(DEFAULT_INBOUND_ROUTER_MAX_IDLE_AGE);
496506
let max_idle =
497507
inbound_max_idle_per_endpoint?.unwrap_or(DEFAULT_INBOUND_MAX_IDLE_CONNS_PER_ENDPOINT);
508+
let connection_pool_timeout = parse(
509+
strings,
510+
ENV_INBOUND_HTTP1_CONNECTION_POOL_IDLE_TIMEOUT,
511+
parse_duration,
512+
)?
513+
.unwrap_or(DEFAULT_INBOUND_HTTP1_CONNECTION_POOL_IDLE_TIMEOUT);
498514
let keepalive = Keepalive(inbound_connect_keepalive?);
499515
let connect = ConnectConfig {
500516
keepalive,
@@ -507,7 +523,7 @@ pub fn parse_config<S: Strings>(strings: &S) -> Result<super::Config, EnvError>
507523
h2_settings,
508524
h1_settings: h1::PoolSettings {
509525
max_idle,
510-
idle_timeout: cache_max_idle_age,
526+
idle_timeout: connection_pool_timeout,
511527
},
512528
};
513529

0 commit comments

Comments
 (0)