]> git.kaiwu.me - nginx.git/commitdiff
Upstream keepalive: distinguish cached connections by location.
authorRoman Semenov <r.semenov@f5.com>
Thu, 19 Mar 2026 19:47:14 +0000 (12:47 -0700)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Tue, 24 Mar 2026 10:28:52 +0000 (14:28 +0400)
The new "local" parameter prevents sharing cached keepalive connections
between location blocks. Connections are now reused only within the same
location.

src/http/modules/ngx_http_upstream_keepalive_module.c

index 8858922a0d2b944df1578df4f6a112d6b9907a25..11875ded811080362982197fac842daab2c1b10d 100644 (file)
@@ -22,6 +22,8 @@ typedef struct {
     ngx_http_upstream_init_pt          original_init_upstream;
     ngx_http_upstream_init_peer_pt     original_init_peer;
 
+    ngx_uint_t                         local; /* unsigned  local:1; */
+
 } ngx_http_upstream_keepalive_srv_conf_t;
 
 
@@ -34,6 +36,8 @@ typedef struct {
     socklen_t                          socklen;
     ngx_sockaddr_t                     sockaddr;
 
+    ngx_http_upstream_conf_t          *tag;
+
 } ngx_http_upstream_keepalive_cache_t;
 
 
@@ -86,7 +90,7 @@ static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
 static ngx_command_t  ngx_http_upstream_keepalive_commands[] = {
 
     { ngx_string("keepalive"),
-      NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
+      NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
       ngx_http_upstream_keepalive,
       NGX_HTTP_SRV_CONF_OFFSET,
       0,
@@ -274,6 +278,10 @@ ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data)
         item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
         c = item->connection;
 
+        if (kp->conf->local && item->tag != kp->upstream->conf) {
+            continue;
+        }
+
         if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
                          item->socklen, pc->socklen)
             == 0)
@@ -387,6 +395,7 @@ ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
     ngx_queue_insert_head(&kp->conf->cache, q);
 
     item->connection = c;
+    item->tag = u->conf;
 
     pc->connection = NULL;
 
@@ -544,6 +553,7 @@ ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
      *     conf->original_init_upstream = NULL;
      *     conf->original_init_peer = NULL;
      *     conf->max_cached = 0;
+     *     conf->local = 0;
      */
 
     conf->time = NGX_CONF_UNSET_MSEC;
@@ -582,6 +592,17 @@ ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     kcf->max_cached = n;
 
+    if (cf->args->nelts == 3) {
+        if (ngx_strncmp(value[2].data, "local", 5) == 0) {
+            kcf->local = 1;
+
+        } else {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "invalid parameter \"%V\"", &value[2]);
+            return NGX_CONF_ERROR;
+        }
+    }
+
     /* init upstream handler */
 
     uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);