Mercurial > hg > nginx
comparison src/core/ngx_connection.c @ 6873:426828549afc
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 20 Jan 2017 14:03:20 +0300 |
parents | 6ed0922d316b |
children | ed1101bbf19f 05bd1baabf87 |
comparison
equal
deleted
inserted
replaced
6872:6ed0922d316b | 6873:426828549afc |
---|---|
1202 ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, | 1202 ngx_log_debug1(NGX_LOG_DEBUG_CORE, c->log, 0, |
1203 "reusable connection: %ui", reusable); | 1203 "reusable connection: %ui", reusable); |
1204 | 1204 |
1205 if (c->reusable) { | 1205 if (c->reusable) { |
1206 ngx_queue_remove(&c->queue); | 1206 ngx_queue_remove(&c->queue); |
1207 ngx_cycle->reusable_connections_n--; | |
1207 | 1208 |
1208 #if (NGX_STAT_STUB) | 1209 #if (NGX_STAT_STUB) |
1209 (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1); | 1210 (void) ngx_atomic_fetch_add(ngx_stat_waiting, -1); |
1210 #endif | 1211 #endif |
1211 } | 1212 } |
1215 if (reusable) { | 1216 if (reusable) { |
1216 /* need cast as ngx_cycle is volatile */ | 1217 /* need cast as ngx_cycle is volatile */ |
1217 | 1218 |
1218 ngx_queue_insert_head( | 1219 ngx_queue_insert_head( |
1219 (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue); | 1220 (ngx_queue_t *) &ngx_cycle->reusable_connections_queue, &c->queue); |
1221 ngx_cycle->reusable_connections_n++; | |
1220 | 1222 |
1221 #if (NGX_STAT_STUB) | 1223 #if (NGX_STAT_STUB) |
1222 (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1); | 1224 (void) ngx_atomic_fetch_add(ngx_stat_waiting, 1); |
1223 #endif | 1225 #endif |
1224 } | 1226 } |
1226 | 1228 |
1227 | 1229 |
1228 static void | 1230 static void |
1229 ngx_drain_connections(ngx_cycle_t *cycle) | 1231 ngx_drain_connections(ngx_cycle_t *cycle) |
1230 { | 1232 { |
1231 ngx_int_t i; | 1233 ngx_uint_t i, n; |
1232 ngx_queue_t *q; | 1234 ngx_queue_t *q; |
1233 ngx_connection_t *c; | 1235 ngx_connection_t *c; |
1234 | 1236 |
1235 for (i = 0; i < 32; i++) { | 1237 n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1); |
1238 | |
1239 for (i = 0; i < n; i++) { | |
1236 if (ngx_queue_empty(&cycle->reusable_connections_queue)) { | 1240 if (ngx_queue_empty(&cycle->reusable_connections_queue)) { |
1237 break; | 1241 break; |
1238 } | 1242 } |
1239 | 1243 |
1240 q = ngx_queue_last(&cycle->reusable_connections_queue); | 1244 q = ngx_queue_last(&cycle->reusable_connections_queue); |