[PATCH] HTTP: keepalive_graceful_close support

Youlin Feng fengyoulin at live.com
Fri Dec 17 05:59:40 UTC 2021


# HG changeset patch
# User Youlin Feng <fengyoulin at live.com>
# Date 1639718067 -28800
#      Fri Dec 17 13:14:27 2021 +0800
# Node ID 54db7272bb0c9040eaf657f92bb02c9147d927e6
# Parent  a7a77549265ef46f1f0fdb3897f4beabf9e09c40
HTTP: keepalive_graceful_close support.

Previously, keepalived connections will be suddenly closed during worker
process exiting, without notification to the client. The client may be
sending a request when the connection is closed, resulting in an error.

With "keepalive_graceful_close on;", the client will receive an
"Connection: close" response header in the last request, then the
connection can be closed gracefully.

diff -r a7a77549265e -r 54db7272bb0c src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c	Thu Nov 25 22:02:10 2021 +0300
+++ b/src/http/ngx_http_core_module.c	Fri Dec 17 13:14:27 2021 +0800
@@ -523,6 +523,13 @@
       offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
       &ngx_http_core_keepalive_disable },
 
+    { ngx_string("keepalive_graceful_close"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, keepalive_graceful_close),
+      NULL },
+
     { ngx_string("satisfy"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_enum_slot,
@@ -826,7 +833,7 @@
     if (!r->internal) {
         switch (r->headers_in.connection_type) {
         case 0:
-            r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
+            r->keepalive = (r->http_version > NGX_HTTP_VERSION_10) && !ngx_exiting;
             break;
 
         case NGX_HTTP_CONNECTION_CLOSE:
@@ -834,7 +841,7 @@
             break;
 
         case NGX_HTTP_CONNECTION_KEEP_ALIVE:
-            r->keepalive = 1;
+            r->keepalive = !ngx_exiting;
             break;
         }
 
@@ -3517,6 +3524,7 @@
     clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
     clcf->keepalive_header = NGX_CONF_UNSET;
     clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
+    clcf->keepalive_graceful_close = NGX_CONF_UNSET;
     clcf->lingering_close = NGX_CONF_UNSET_UINT;
     clcf->lingering_time = NGX_CONF_UNSET_MSEC;
     clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
@@ -3756,6 +3764,8 @@
                               prev->keepalive_header, 0);
     ngx_conf_merge_uint_value(conf->keepalive_requests,
                               prev->keepalive_requests, 1000);
+    ngx_conf_merge_value(conf->keepalive_graceful_close,
+                              prev->keepalive_graceful_close, 0);
     ngx_conf_merge_uint_value(conf->lingering_close,
                               prev->lingering_close, NGX_HTTP_LINGERING_ON);
     ngx_conf_merge_msec_value(conf->lingering_time,
diff -r a7a77549265e -r 54db7272bb0c src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h	Thu Nov 25 22:02:10 2021 +0300
+++ b/src/http/ngx_http_core_module.h	Fri Dec 17 13:14:27 2021 +0800
@@ -371,6 +371,8 @@
 
     time_t        keepalive_header;        /* keepalive_timeout */
 
+    ngx_flag_t    keepalive_graceful_close; /* keepalive_graceful_close */
+
     ngx_uint_t    keepalive_requests;      /* keepalive_requests */
     ngx_uint_t    keepalive_disable;       /* keepalive_disable */
     ngx_uint_t    satisfy;                 /* satisfy */
diff -r a7a77549265e -r 54db7272bb0c src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c	Thu Nov 25 22:02:10 2021 +0300
+++ b/src/http/ngx_http_request.c	Fri Dec 17 13:14:27 2021 +0800
@@ -2767,7 +2767,7 @@
     }
 
     if (!ngx_terminate
-         && !ngx_exiting
+         && (!ngx_exiting || clcf->keepalive_graceful_close)
          && r->keepalive
          && clcf->keepalive_timeout > 0)
     {
@@ -3252,7 +3252,7 @@
     r->http_state = NGX_HTTP_KEEPALIVE_STATE;
 #endif
 
-    c->idle = 1;
+    c->idle = !clcf->keepalive_graceful_close;
     ngx_reusable_connection(c, 1);
 
     ngx_add_timer(rev, clcf->keepalive_timeout);



More information about the nginx-devel mailing list