[PATCH] Delayed closing of idle connections
Sunggon Song
sunggon.song at quantil.com
Wed Jul 17 01:08:13 UTC 2024
# HG changeset patch
# User Sunggon Song <sunggon.song at quantil.com>
# Date 1721178360 -32400
# Wed Jul 17 10:06:00 2024 +0900
# Node ID 3db2df01147dcbcc7bc63670207a0aa2439f6a8c
# Parent 072ca4906154effb64cbf8209dfe86742ff074d7
[PATCH] Delayed closing of idle connections
Delays processing of closing idle connection to read unread requests
while nginx performs a graceful shutdown.
This is the case where the client sent the request message
through the keepalive(idle) connection, but nginx has not yet read it
from the socket recv buffer.
If there is no delay time and there are some unread requests
in the socket recv buffer, the idle connection is immediately closed
and a TCP reset is sent to the client by the TCP stack of the kernel.
diff -r 072ca4906154 -r 3db2df01147d src/core/nginx.c
--- a/src/core/nginx.c Thu Jun 27 17:29:56 2024 +0400
+++ b/src/core/nginx.c Wed Jul 17 10:06:00 2024 +0900
@@ -153,6 +153,13 @@
0,
NULL },
+ { ngx_string("close_idle_connections_delay"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_close_idle_connecions_delay,
+ 0,
+ offsetof(ngx_core_conf_t, close_idle_connections_delay),
+ NULL },
+
ngx_null_command
};
@@ -1125,6 +1132,8 @@
ccf->user = (ngx_uid_t) NGX_CONF_UNSET_UINT;
ccf->group = (ngx_gid_t) NGX_CONF_UNSET_UINT;
+ ccf->close_idle_connections_delay = NGX_CONF_UNSET;
+
if (ngx_array_init(&ccf->env, cycle->pool, 1, sizeof(ngx_str_t))
!= NGX_OK)
{
@@ -1148,6 +1157,8 @@
ngx_conf_init_value(ccf->worker_processes, 1);
ngx_conf_init_value(ccf->debug_points, 0);
+ ngx_conf_init_value(ccf->close_idle_connections_delay, 0);
+
#if (NGX_HAVE_CPU_AFFINITY)
if (!ccf->cpu_affinity_auto
diff -r 072ca4906154 -r 3db2df01147d src/core/ngx_conf_file.c
--- a/src/core/ngx_conf_file.c Thu Jun 27 17:29:56 2024 +0400
+++ b/src/core/ngx_conf_file.c Wed Jul 17 10:06:00 2024 +0900
@@ -1484,3 +1484,31 @@
return NGX_CONF_ERROR;
}
+
+char *
+ngx_conf_set_close_idle_connecions_delay(ngx_conf_t *cf, ngx_command_t
*cmd,
+ void *conf)
+{
+ char *p = conf;
+
+ time_t *sp;
+ ngx_str_t *value;
+
+ sp = (time_t *) (p + cmd->offset);
+ if (*sp != NGX_CONF_UNSET) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ *sp = ngx_parse_time(&value[1], 1);
+
+ if (*sp == (time_t) NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid value \"%s\"", value[i].data);
+
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
diff -r 072ca4906154 -r 3db2df01147d src/core/ngx_conf_file.h
--- a/src/core/ngx_conf_file.h Thu Jun 27 17:29:56 2024 +0400
+++ b/src/core/ngx_conf_file.h Wed Jul 17 10:06:00 2024 +0900
@@ -290,6 +290,7 @@
char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void
*conf);
char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void
*conf);
char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void
*conf);
-
+char *ngx_conf_set_close_idle_connecions_delay(ngx_conf_t *cf,
+ ngx_command_t *cmd, void *conf);
#endif /* _NGX_CONF_FILE_H_INCLUDED_ */
diff -r 072ca4906154 -r 3db2df01147d src/core/ngx_cycle.h
--- a/src/core/ngx_cycle.h Thu Jun 27 17:29:56 2024 +0400
+++ b/src/core/ngx_cycle.h Wed Jul 17 10:06:00 2024 +0900
@@ -118,6 +118,8 @@
ngx_array_t env;
char **environment;
+ time_t close_idle_connections_delay;
+
ngx_uint_t transparent; /* unsigned transparent:1; */
} ngx_core_conf_t;
diff -r 072ca4906154 -r 3db2df01147d src/os/unix/ngx_process_cycle.c
--- a/src/os/unix/ngx_process_cycle.c Thu Jun 27 17:29:56 2024 +0400
+++ b/src/os/unix/ngx_process_cycle.c Wed Jul 17 10:06:00 2024 +0900
@@ -51,6 +51,7 @@
sig_atomic_t ngx_noaccept;
ngx_uint_t ngx_noaccepting;
ngx_uint_t ngx_restart;
+ngx_uint_t ngx_delayed_close_done;
static u_char master_process[] = "master process";
@@ -698,6 +699,9 @@
static void
ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
{
+ time_t now;
+ ngx_core_conf_t *ccf;
+ time_t delay_sec;
ngx_int_t worker = (intptr_t) data;
ngx_process = NGX_PROCESS_WORKER;
@@ -706,10 +710,26 @@
ngx_worker_process_init(cycle, worker);
ngx_setproctitle("worker process");
+ delay_sec = 0;
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
for ( ;; ) {
if (ngx_exiting) {
+ now = ngx_time();
+ if (ccf->close_idle_connections_delay &&
+ !ngx_delayed_close_done)
+ {
+
+ if (!delay_sec) {
+ delay_sec = now + ccf->close_idle_connections_delay;
+ } else {
+ if (delay_sec < now) {
+ ngx_close_idle_connections(cycle);
+ ngx_delayed_close_done = 1;
+ }
+ }
+ }
if (ngx_event_no_timers_left() == NGX_OK) {
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
ngx_worker_process_exit(cycle);
@@ -735,7 +755,9 @@
ngx_exiting = 1;
ngx_set_shutdown_timer(cycle);
ngx_close_listening_sockets(cycle);
- ngx_close_idle_connections(cycle);
+ if (!ccf->close_idle_connections_delay) {
+ ngx_close_idle_connections(cycle);
+ }
ngx_event_process_posted(cycle, &ngx_posted_events);
}
}
@@ -941,6 +963,16 @@
{
ngx_uint_t i;
ngx_connection_t *c;
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
+
+ if (ccf->close_idle_connections_delay &&
+ !ngx_delayed_close_done)
+ {
+ ngx_close_idle_connections(cycle);
+ ngx_delayed_close_done = 1;
+ }
for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->exit_process) {
Best Regards and thanks,
Sunggon
---------------------------------------------------------------------
Sunggon Song I Principal Research Engineer
Cache Team
Office. 82-2-3441-0375 Cell. 82-10-8744-0133
E-mail. sunggon.song at cdnetworks.co.kr, sunggon.song at quantil.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20240717/316fcbe9/attachment-0001.htm>
More information about the nginx-devel
mailing list