summaryrefslogtreecommitdiffhomepage
path: root/src/http/modules
diff options
context:
space:
mode:
authorRoman Semenov <r.semenov@f5.com>2026-03-23 11:03:26 -0700
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>2026-03-24 14:28:52 +0400
commit4fbe4b62746f67d4348212c089b745bd10082964 (patch)
tree9022aa586bbaeb16f3410b60a47380a276595933 /src/http/modules
parentc5d36eac33d7c2198240111819b2a1c9fcb593a4 (diff)
downloadnginx-4fbe4b62746f67d4348212c089b745bd10082964.tar.gz
nginx-4fbe4b62746f67d4348212c089b745bd10082964.tar.bz2
Upstream: enabled keepalive by default for explicit upstreams.
Keepalive is now automatically enabled in the "local" mode for upstreams defined in configuration files. Cached keepalive connections are no longer shared between different locations referencing the same explicit upstream unless keepalive is explicitly configured without the "local" parameter. To disable keepalive entirely, use keepalive 0; inside the upstream block. To allow sharing cached connections between locations, configure keepalive <max_cached>; without the "local" parameter.
Diffstat (limited to 'src/http/modules')
-rw-r--r--src/http/modules/ngx_http_upstream_keepalive_module.c130
1 files changed, 67 insertions, 63 deletions
diff --git a/src/http/modules/ngx_http_upstream_keepalive_module.c b/src/http/modules/ngx_http_upstream_keepalive_module.c
index 11875ded8..121023e30 100644
--- a/src/http/modules/ngx_http_upstream_keepalive_module.c
+++ b/src/http/modules/ngx_http_upstream_keepalive_module.c
@@ -19,7 +19,6 @@ typedef struct {
ngx_queue_t cache;
ngx_queue_t free;
- ngx_http_upstream_init_pt original_init_upstream;
ngx_http_upstream_init_peer_pt original_init_peer;
ngx_uint_t local; /* unsigned local:1; */
@@ -83,6 +82,8 @@ static void ngx_http_upstream_notify_keepalive_peer(ngx_peer_connection_t *pc,
void *data, ngx_uint_t type);
static void *ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf);
+static char *ngx_http_upstream_keepalive_init_main_conf(ngx_conf_t *cf,
+ void *conf);
static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -126,7 +127,7 @@ static ngx_http_module_t ngx_http_upstream_keepalive_module_ctx = {
NULL, /* postconfiguration */
NULL, /* create main configuration */
- NULL, /* init main configuration */
+ ngx_http_upstream_keepalive_init_main_conf, /* init main configuration */
ngx_http_upstream_keepalive_create_conf, /* create server configuration */
NULL, /* merge server configuration */
@@ -153,52 +154,6 @@ ngx_module_t ngx_http_upstream_keepalive_module = {
static ngx_int_t
-ngx_http_upstream_init_keepalive(ngx_conf_t *cf,
- ngx_http_upstream_srv_conf_t *us)
-{
- ngx_uint_t i;
- ngx_http_upstream_keepalive_srv_conf_t *kcf;
- ngx_http_upstream_keepalive_cache_t *cached;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "init keepalive");
-
- kcf = ngx_http_conf_upstream_srv_conf(us,
- ngx_http_upstream_keepalive_module);
-
- ngx_conf_init_msec_value(kcf->time, 3600000);
- ngx_conf_init_msec_value(kcf->timeout, 60000);
- ngx_conf_init_uint_value(kcf->requests, 1000);
-
- if (kcf->original_init_upstream(cf, us) != NGX_OK) {
- return NGX_ERROR;
- }
-
- kcf->original_init_peer = us->peer.init;
-
- us->peer.init = ngx_http_upstream_init_keepalive_peer;
-
- /* allocate cache items and add to free queue */
-
- cached = ngx_pcalloc(cf->pool,
- sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached);
- if (cached == NULL) {
- return NGX_ERROR;
- }
-
- ngx_queue_init(&kcf->cache);
- ngx_queue_init(&kcf->free);
-
- for (i = 0; i < kcf->max_cached; i++) {
- ngx_queue_insert_head(&kcf->free, &cached[i].queue);
- cached[i].conf = kcf;
- }
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
ngx_http_upstream_srv_conf_t *us)
{
@@ -550,30 +505,89 @@ ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
/*
* set by ngx_pcalloc():
*
- * conf->original_init_upstream = NULL;
* conf->original_init_peer = NULL;
- * conf->max_cached = 0;
* conf->local = 0;
*/
conf->time = NGX_CONF_UNSET_MSEC;
conf->timeout = NGX_CONF_UNSET_MSEC;
conf->requests = NGX_CONF_UNSET_UINT;
+ conf->max_cached = NGX_CONF_UNSET_UINT;
return conf;
}
static char *
+ngx_http_upstream_keepalive_init_main_conf(ngx_conf_t *cf, void *conf)
+{
+ ngx_uint_t i, j;
+ ngx_http_upstream_srv_conf_t **uscfp;
+ ngx_http_upstream_main_conf_t *umcf;
+ ngx_http_upstream_keepalive_cache_t *cached;
+ ngx_http_upstream_keepalive_srv_conf_t *kcf;
+
+ umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
+
+ uscfp = umcf->upstreams.elts;
+
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
+
+ /* skip implicit upstreams */
+ if (uscfp[i]->srv_conf == NULL) {
+ continue;
+ }
+
+ kcf = ngx_http_conf_upstream_srv_conf(uscfp[i],
+ ngx_http_upstream_keepalive_module);
+
+ if (kcf->max_cached == 0) {
+ continue;
+ }
+
+ ngx_conf_init_msec_value(kcf->time, 3600000);
+ ngx_conf_init_msec_value(kcf->timeout, 60000);
+ ngx_conf_init_uint_value(kcf->requests, 1000);
+
+ if (kcf->max_cached == NGX_CONF_UNSET_UINT) {
+ kcf->local = 1;
+ kcf->max_cached = 32;
+ }
+
+ kcf->original_init_peer = uscfp[i]->peer.init;
+
+ uscfp[i]->peer.init = ngx_http_upstream_init_keepalive_peer;
+
+ /* allocate cache items and add to free queue */
+
+ cached = ngx_pcalloc(cf->pool,
+ sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached);
+ if (cached == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_queue_init(&kcf->cache);
+ ngx_queue_init(&kcf->free);
+
+ for (j = 0; j < kcf->max_cached; j++) {
+ ngx_queue_insert_head(&kcf->free, &cached[j].queue);
+ cached[j].conf = kcf;
+ }
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_upstream_srv_conf_t *uscf;
ngx_http_upstream_keepalive_srv_conf_t *kcf = conf;
ngx_int_t n;
ngx_str_t *value;
- if (kcf->max_cached) {
+ if (kcf->max_cached != NGX_CONF_UNSET_UINT) {
return "is duplicate";
}
@@ -583,7 +597,7 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
n = ngx_atoi(value[1].data, value[1].len);
- if (n == NGX_ERROR || n == 0) {
+ if (n == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid value \"%V\" in \"%V\" directive",
&value[1], &cmd->name);
@@ -603,15 +617,5 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
- /* init upstream handler */
-
- uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
-
- kcf->original_init_upstream = uscf->peer.init_upstream
- ? uscf->peer.init_upstream
- : ngx_http_upstream_init_round_robin;
-
- uscf->peer.init_upstream = ngx_http_upstream_init_keepalive;
-
return NGX_CONF_OK;
}