[nginx] Introduced worker_shutdown_timeout.
洪志道
hongzhidao at gmail.com
Wed Mar 8 07:52:15 UTC 2017
Hi!
It's a good design.
It seems the worker process is not killed until expired, the time is set by
'worker_shutdown_timeout'.
But I think ngx_shutdown_timer_handler will never be called, because of the
following deal.
if (ngx_exiting) {
if (ngx_event_no_timers_left() == NGX_OK) {
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
ngx_worker_process_exit(cycle); // the worker process
exits though there are cancelable timers such as ngx_shutdown_event.
}
}
I'm not sure it's right?
diff -r d45072375572 src/core/ngx_cycle.c
--- a/src/core/ngx_cycle.c Tue Mar 07 18:51:17 2017 +0300
+++ b/src/core/ngx_cycle.c Sun Mar 05 17:03:22 2017 +0800
@@ -1348,7 +1348,6 @@
ngx_shutdown_event.handler = ngx_shutdown_timer_handler;
ngx_shutdown_event.data = cycle;
ngx_shutdown_event.log = cycle->log;
- ngx_shutdown_event.cancelable = 1;
ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout);
}
And I think it's better that the shutting down process keep alive until '
worker_shutdown_timeout'.
Thanks.
B.R.
2017-03-08 1:01 GMT+08:00 Maxim Dounin <mdounin at mdounin.ru>:
> details: http://hg.nginx.org/nginx/rev/97c99bb43737
> branches:
> changeset: 6930:97c99bb43737
> user: Maxim Dounin <mdounin at mdounin.ru>
> date: Tue Mar 07 18:51:16 2017 +0300
> description:
> Introduced worker_shutdown_timeout.
>
> The directive configures a timeout to be used when gracefully shutting down
> worker processes. When the timer expires, nginx will try to close all
> the connections currently open to facilitate shutdown.
>
> diffstat:
>
> src/core/nginx.c | 9 ++++++
> src/core/ngx_cycle.c | 53 ++++++++++++++++++++++++++++++
> ++++++++++
> src/core/ngx_cycle.h | 2 +
> src/os/unix/ngx_process_cycle.c | 1 +
> src/os/win32/ngx_process_cycle.c | 1 +
> 5 files changed, 66 insertions(+), 0 deletions(-)
>
> diffs (148 lines):
>
> diff --git a/src/core/nginx.c b/src/core/nginx.c
> --- a/src/core/nginx.c
> +++ b/src/core/nginx.c
> @@ -124,6 +124,13 @@ static ngx_command_t ngx_core_commands[
> offsetof(ngx_core_conf_t, rlimit_core),
> NULL },
>
> + { ngx_string("worker_shutdown_timeout"),
> + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
> + ngx_conf_set_msec_slot,
> + 0,
> + offsetof(ngx_core_conf_t, shutdown_timeout),
> + NULL },
> +
> { ngx_string("working_directory"),
> NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
> ngx_conf_set_str_slot,
> @@ -1014,6 +1021,7 @@ ngx_core_module_create_conf(ngx_cycle_t
> ccf->daemon = NGX_CONF_UNSET;
> ccf->master = NGX_CONF_UNSET;
> ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
> + ccf->shutdown_timeout = NGX_CONF_UNSET_MSEC;
>
> ccf->worker_processes = NGX_CONF_UNSET;
> ccf->debug_points = NGX_CONF_UNSET;
> @@ -1042,6 +1050,7 @@ ngx_core_module_init_conf(ngx_cycle_t *c
> ngx_conf_init_value(ccf->daemon, 1);
> ngx_conf_init_value(ccf->master, 1);
> ngx_conf_init_msec_value(ccf->timer_resolution, 0);
> + ngx_conf_init_msec_value(ccf->shutdown_timeout, 0);
>
> ngx_conf_init_value(ccf->worker_processes, 1);
> ngx_conf_init_value(ccf->debug_points, 0);
> diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
> --- a/src/core/ngx_cycle.c
> +++ b/src/core/ngx_cycle.c
> @@ -15,6 +15,7 @@ static ngx_int_t ngx_init_zone_pool(ngx_
> ngx_shm_zone_t *shm_zone);
> static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
> static void ngx_clean_old_cycles(ngx_event_t *ev);
> +static void ngx_shutdown_timer_handler(ngx_event_t *ev);
>
>
> volatile ngx_cycle_t *ngx_cycle;
> @@ -22,6 +23,7 @@ ngx_array_t ngx_old_cycles;
>
> static ngx_pool_t *ngx_temp_pool;
> static ngx_event_t ngx_cleaner_event;
> +static ngx_event_t ngx_shutdown_event;
>
> ngx_uint_t ngx_test_config;
> ngx_uint_t ngx_dump_config;
> @@ -1333,3 +1335,54 @@ ngx_clean_old_cycles(ngx_event_t *ev)
> ngx_old_cycles.nelts = 0;
> }
> }
> +
> +
> +void
> +ngx_set_shutdown_timer(ngx_cycle_t *cycle)
> +{
> + ngx_core_conf_t *ccf;
> +
> + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
> ngx_core_module);
> +
> + if (ccf->shutdown_timeout) {
> + ngx_shutdown_event.handler = ngx_shutdown_timer_handler;
> + ngx_shutdown_event.data = cycle;
> + ngx_shutdown_event.log = cycle->log;
> + ngx_shutdown_event.cancelable = 1;
> +
> + ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout);
> + }
> +}
> +
> +
> +static void
> +ngx_shutdown_timer_handler(ngx_event_t *ev)
> +{
> + ngx_uint_t i;
> + ngx_cycle_t *cycle;
> + ngx_connection_t *c;
> +
> + cycle = ev->data;
> +
> + c = cycle->connections;
> +
> + for (i = 0; i < cycle->connection_n; i++) {
> +
> + if (c[i].fd == (ngx_socket_t) -1
> + || c[i].read == NULL
> + || c[i].read->accept
> + || c[i].read->channel
> + || c[i].read->resolver)
> + {
> + continue;
> + }
> +
> + ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
> + "*%uA shutdown timeout", c[i].number);
> +
> + c[i].close = 1;
> + c[i].error = 1;
> +
> + c[i].read->handler(c[i].read);
> + }
> +}
> diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
> --- a/src/core/ngx_cycle.h
> +++ b/src/core/ngx_cycle.h
> @@ -88,6 +88,7 @@ typedef struct {
> ngx_flag_t master;
>
> ngx_msec_t timer_resolution;
> + ngx_msec_t shutdown_timeout;
>
> ngx_int_t worker_processes;
> ngx_int_t debug_points;
> @@ -129,6 +130,7 @@ ngx_pid_t ngx_exec_new_binary(ngx_cycle_
> ngx_cpuset_t *ngx_get_cpu_affinity(ngx_uint_t n);
> ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
> size_t size, void *tag);
> +void ngx_set_shutdown_timer(ngx_cycle_t *cycle);
>
>
> extern volatile ngx_cycle_t *ngx_cycle;
> diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_
> cycle.c
> --- a/src/os/unix/ngx_process_cycle.c
> +++ b/src/os/unix/ngx_process_cycle.c
> @@ -763,6 +763,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cy
>
> if (!ngx_exiting) {
> ngx_exiting = 1;
> + ngx_set_shutdown_timer(cycle);
> ngx_close_listening_sockets(cycle);
> ngx_close_idle_connections(cycle);
> }
> diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_
> cycle.c
> --- a/src/os/win32/ngx_process_cycle.c
> +++ b/src/os/win32/ngx_process_cycle.c
> @@ -800,6 +800,7 @@ ngx_worker_thread(void *data)
>
> if (!ngx_exiting) {
> ngx_exiting = 1;
> + ngx_set_shutdown_timer(cycle);
> ngx_close_listening_sockets(cycle);
> ngx_close_idle_connections(cycle);
> }
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20170308/3157b2e3/attachment-0001.html>
More information about the nginx-devel
mailing list