comparison src/http/modules/ngx_http_upstream_keepalive_module.c @ 7339:d9029e113a05

Upstream keepalive: keepalive_timeout directive. The directive configures maximum time a connection can be kept in the cache. By configuring a time which is smaller than the corresponding timeout on the backend side one can avoid the race between closing a connection by the backend and nginx trying to use the same connection to send a request at the same time.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 10 Aug 2018 21:54:23 +0300
parents 46174066b75f
children 70c6b08973a0
comparison
equal deleted inserted replaced
7338:46174066b75f 7339:d9029e113a05
10 #include <ngx_http.h> 10 #include <ngx_http.h>
11 11
12 12
13 typedef struct { 13 typedef struct {
14 ngx_uint_t max_cached; 14 ngx_uint_t max_cached;
15 ngx_msec_t timeout;
15 16
16 ngx_queue_t cache; 17 ngx_queue_t cache;
17 ngx_queue_t free; 18 ngx_queue_t free;
18 19
19 ngx_http_upstream_init_pt original_init_upstream; 20 ngx_http_upstream_init_pt original_init_upstream;
80 { ngx_string("keepalive"), 81 { ngx_string("keepalive"),
81 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1, 82 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
82 ngx_http_upstream_keepalive, 83 ngx_http_upstream_keepalive,
83 NGX_HTTP_SRV_CONF_OFFSET, 84 NGX_HTTP_SRV_CONF_OFFSET,
84 0, 85 0,
86 NULL },
87
88 { ngx_string("keepalive_timeout"),
89 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
90 ngx_conf_set_msec_slot,
91 NGX_HTTP_SRV_CONF_OFFSET,
92 offsetof(ngx_http_upstream_keepalive_srv_conf_t, timeout),
85 NULL }, 93 NULL },
86 94
87 ngx_null_command 95 ngx_null_command
88 }; 96 };
89 97
131 "init keepalive"); 139 "init keepalive");
132 140
133 kcf = ngx_http_conf_upstream_srv_conf(us, 141 kcf = ngx_http_conf_upstream_srv_conf(us,
134 ngx_http_upstream_keepalive_module); 142 ngx_http_upstream_keepalive_module);
135 143
144 ngx_conf_init_msec_value(kcf->timeout, 60000);
145
136 if (kcf->original_init_upstream(cf, us) != NGX_OK) { 146 if (kcf->original_init_upstream(cf, us) != NGX_OK) {
137 return NGX_ERROR; 147 return NGX_ERROR;
138 } 148 }
139 149
140 kcf->original_init_peer = us->peer.init; 150 kcf->original_init_peer = us->peer.init;
258 c->sent = 0; 268 c->sent = 0;
259 c->log = pc->log; 269 c->log = pc->log;
260 c->read->log = pc->log; 270 c->read->log = pc->log;
261 c->write->log = pc->log; 271 c->write->log = pc->log;
262 c->pool->log = pc->log; 272 c->pool->log = pc->log;
273
274 if (c->read->timer_set) {
275 ngx_del_timer(c->read);
276 }
263 277
264 pc->connection = c; 278 pc->connection = c;
265 pc->cached = 1; 279 pc->cached = 1;
266 280
267 return NGX_DONE; 281 return NGX_DONE;
337 351
338 item->connection = c; 352 item->connection = c;
339 353
340 pc->connection = NULL; 354 pc->connection = NULL;
341 355
342 if (c->read->timer_set) { 356 c->read->delayed = 0;
343 c->read->delayed = 0; 357 ngx_add_timer(c->read, kp->conf->timeout);
344 ngx_del_timer(c->read); 358
345 }
346 if (c->write->timer_set) { 359 if (c->write->timer_set) {
347 ngx_del_timer(c->write); 360 ngx_del_timer(c->write);
348 } 361 }
349 362
350 c->write->handler = ngx_http_upstream_keepalive_dummy_handler; 363 c->write->handler = ngx_http_upstream_keepalive_dummy_handler;
391 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, 404 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
392 "keepalive close handler"); 405 "keepalive close handler");
393 406
394 c = ev->data; 407 c = ev->data;
395 408
396 if (c->close) { 409 if (c->close || c->read->timedout) {
397 goto close; 410 goto close;
398 } 411 }
399 412
400 n = recv(c->fd, buf, 1, MSG_PEEK); 413 n = recv(c->fd, buf, 1, MSG_PEEK);
401 414
484 * conf->original_init_upstream = NULL; 497 * conf->original_init_upstream = NULL;
485 * conf->original_init_peer = NULL; 498 * conf->original_init_peer = NULL;
486 * conf->max_cached = 0; 499 * conf->max_cached = 0;
487 */ 500 */
488 501
502 conf->timeout = NGX_CONF_UNSET_MSEC;
503
489 return conf; 504 return conf;
490 } 505 }
491 506
492 507
493 static char * 508 static char *