[PATCH] Introduced worker_shutdown_idle_delay
Roman Arutyunyan
arut at nginx.com
Fri Jan 26 07:03:31 UTC 2024
Hi Artem,
On Wed, Nov 08, 2023 at 07:51:39AM +0300, Artem Pogartsev via nginx-devel wrote:
> # HG changeset patch
> # User Artem Pogartsev <iam at arteomp.com>
> # Date 1699416491 -10800
> # Wed Nov 08 07:08:11 2023 +0300
> # Node ID eb0dd3d903431f4dd7a62d629db457ecddeadd96
> # Parent 7ec761f0365f418511e30b82e9adf80bc56681df
> Introduced worker_shutdown_idle_delay.
>
> The directive configures a delay before closing idle connections to be used
> when gracefully shutting down worker processes. When the timer expires, nginx
> will attempt to close any remaining idle connections.
>
> The delay is only added for connections with the "shutdown_delay" flag, and
> currently it's only keepalive HTTP/1.1 connections. The behavior is not changed
> for protocols that have built-in graceful shutdown mechanisms, such as GOAWAY
> frames in HTTP2 and HTTP3.
>
> Although it's perfectly fine to close an HTTP/1.1 connection at any time
> according to RFC 9112, it may still be useful to delay closing a connection,
> wait for the next client request, and close the connection with a
> "Connection: close" header to avoid unnecessary retries by clients. This is
> especially important for environments with frequent nginx reloads and large
> amounts of non-idempotent requests which are quite problematic for automatic
> retries.
>
> Should be used carefully to not delay configuration reloads too much (and thus
> increase nginx resource usage), and ideally in combination with properly
> configured clients:
[..]
I suggest a simpler patch which disables idle mode for HTTP keepalive
connections. Such connections will not be closed until one of the timeouts
(keepalive_timeout or worker_shutdown_timeout) expires or when a new request
arrives and receives 'Connection: close'.
--
Roman Arutyunyan
-------------- next part --------------
# HG changeset patch
# User Roman Arutyunyan <arut at nginx.com>
# Date 1706205992 -14400
# Thu Jan 25 22:06:32 2024 +0400
# Node ID 165096c37f91640042e93f115b7281a3c690bc9d
# Parent d9bc503a4c39d29480e640347e0b992d83c792bc
Added "keepalive_worker_shutdown" directive.
The directive allows disabling idle mode for HTTP keepalive connections.
Such a connection will not be closed on worker shutdown until a new request is
received on that connection or one of keepalive_timeout/worker_shutdown_timeout
expires.
By default idle mode is enabled, as before.
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -523,6 +523,13 @@ static ngx_command_t ngx_http_core_comm
offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
&ngx_http_core_keepalive_disable },
+ { ngx_string("keepalive_worker_shutdown"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, keepalive_shutdown),
+ NULL },
+
{ ngx_string("satisfy"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_enum_slot,
@@ -3607,6 +3614,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t
clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
clcf->keepalive_header = NGX_CONF_UNSET;
clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
+ clcf->keepalive_shutdown = NGX_CONF_UNSET;
clcf->lingering_close = NGX_CONF_UNSET_UINT;
clcf->lingering_time = NGX_CONF_UNSET_MSEC;
clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
@@ -3897,6 +3905,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t
ngx_conf_merge_value(conf->chunked_transfer_encoding,
prev->chunked_transfer_encoding, 1);
ngx_conf_merge_value(conf->etag, prev->etag, 1);
+ ngx_conf_merge_value(conf->keepalive_shutdown, prev->keepalive_shutdown, 1);
ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens,
NGX_HTTP_SERVER_TOKENS_ON);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -407,6 +407,7 @@ struct ngx_http_core_loc_conf_s {
ngx_uint_t server_tokens; /* server_tokens */
ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */
ngx_flag_t etag; /* etag */
+ ngx_flag_t keepalive_shutdown; /* keepalive_worker_shutdown */
#if (NGX_HTTP_GZIP)
ngx_flag_t gzip_vary; /* gzip_vary */
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -3302,7 +3302,10 @@ ngx_http_set_keepalive(ngx_http_request_
r->http_state = NGX_HTTP_KEEPALIVE_STATE;
#endif
- c->idle = 1;
+ if (clcf->keepalive_shutdown) {
+ c->idle = 1;
+ }
+
ngx_reusable_connection(c, 1);
ngx_add_timer(rev, clcf->keepalive_timeout);
More information about the nginx-devel
mailing list