# HG changeset patch # User Maxim Dounin # Date 1484910200 -10800 # Node ID 426828549afcd91066eadf08d05d08825c091035 # Parent 6ed0922d316b8b571d0df52aad55ddcf741ff85c Improved connection draining with small number of connections. Closing up to 32 connections might be too aggressive if worker_connections is set to a comparable number (and/or there are only a small number of reusable connections). If an occasional connection shorage happens in such a configuration, it leads to closing all reusable connections instead of gradually reducing keepalive timeout to a smaller value. To improve granularity in such configurations we now close no more than 1/8 of all reusable connections at once. Suggested by Joel Cunningham. diff -r 6ed0922d316b -r 426828549afc src/core/ngx_connection.c --- a/src/core/ngx_connection.c Fri Jan 20 14:03:19 2017 +0300 +++ b/src/core/ngx_connection.c Fri Jan 20 14:03:20 2017 +0300 @@ -1204,6 +1204,7 @@ if (c->reusable) { ngx_queue_remove(&c->queue); + ngx_cycle->reusable_connections_n--; #if (NGX_STAT_STUB) (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1); @@ -1217,6 +1218,7 @@ ngx_queue_insert_head( (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue); + ngx_cycle->reusable_connections_n++; #if (NGX_STAT_STUB) (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1); @@ -1228,11 +1230,13 @@ static void ngx_drain_connections(ngx_cycle_t *cycle) { - ngx_int_t i; + ngx_uint_t i, n; ngx_queue_t *q; ngx_connection_t *c; - for (i = 0; i < 32; i++) { + n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1); + + for (i = 0; i < n; i++) { if (ngx_queue_empty(&cycle->reusable_connections_queue)) { break; } diff -r 6ed0922d316b -r 426828549afc src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h Fri Jan 20 14:03:19 2017 +0300 +++ b/src/core/ngx_cycle.h Fri Jan 20 14:03:20 2017 +0300 @@ -53,6 +53,7 @@ ngx_uint_t modules_used; /* unsigned modules_used:1; */ ngx_queue_t reusable_connections_queue; + ngx_uint_t reusable_connections_n; ngx_array_t listening; ngx_array_t paths;