]> git.kaiwu.me - nginx.git/commitdiff
Upstream: max_conns.
authorRuslan Ermilov <ru@nginx.com>
Thu, 22 Sep 2016 16:32:47 +0000 (19:32 +0300)
committerRuslan Ermilov <ru@nginx.com>
Thu, 22 Sep 2016 16:32:47 +0000 (19:32 +0300)
13 files changed:
src/http/modules/ngx_http_upstream_hash_module.c
src/http/modules/ngx_http_upstream_ip_hash_module.c
src/http/modules/ngx_http_upstream_least_conn_module.c
src/http/ngx_http_upstream.c
src/http/ngx_http_upstream.h
src/http/ngx_http_upstream_round_robin.c
src/http/ngx_http_upstream_round_robin.h
src/stream/ngx_stream_upstream.c
src/stream/ngx_stream_upstream.h
src/stream/ngx_stream_upstream_hash_module.c
src/stream/ngx_stream_upstream_least_conn_module.c
src/stream/ngx_stream_upstream_round_robin.c
src/stream/ngx_stream_upstream_round_robin.h

index 669916560be642a4f8cad276a5345d7b6612fc40..6c28c6456e97b1fe3ec723cddf8ae9f54a2dab78 100644 (file)
@@ -242,6 +242,10 @@ ngx_http_upstream_get_hash_peer(ngx_peer_connection_t *pc, void *data)
             goto next;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            goto next;
+        }
+
         break;
 
     next:
@@ -548,6 +552,10 @@ ngx_http_upstream_get_chash_peer(ngx_peer_connection_t *pc, void *data)
                 continue;
             }
 
+            if (peer->max_conns && peer->conns >= peer->max_conns) {
+                continue;
+            }
+
             peer->current_weight += peer->effective_weight;
             total += peer->effective_weight;
 
@@ -647,6 +655,7 @@ ngx_http_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf->flags = NGX_HTTP_UPSTREAM_CREATE
                   |NGX_HTTP_UPSTREAM_WEIGHT
+                  |NGX_HTTP_UPSTREAM_MAX_CONNS
                   |NGX_HTTP_UPSTREAM_MAX_FAILS
                   |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
                   |NGX_HTTP_UPSTREAM_DOWN;
index 8a5f0fa3a07cdad83d870b1e11ecc5b3df8a2166..296108fdb3012d104a05368a25e6f905699c6ffc 100644 (file)
@@ -212,6 +212,10 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
             goto next;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            goto next;
+        }
+
         break;
 
     next:
@@ -259,6 +263,7 @@ ngx_http_upstream_ip_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf->flags = NGX_HTTP_UPSTREAM_CREATE
                   |NGX_HTTP_UPSTREAM_WEIGHT
+                  |NGX_HTTP_UPSTREAM_MAX_CONNS
                   |NGX_HTTP_UPSTREAM_MAX_FAILS
                   |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
                   |NGX_HTTP_UPSTREAM_DOWN;
index 00644a000eb9da2329fc75eea526fd3c47af3b69..ebe06276d5740fcb2803e3f19f8380ff2764ee8e 100644 (file)
@@ -154,6 +154,10 @@ ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
             continue;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            continue;
+        }
+
         /*
          * select peer with least number of connections; if there are
          * multiple peers with the same number of connections, select
@@ -209,6 +213,10 @@ ngx_http_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
                 continue;
             }
 
+            if (peer->max_conns && peer->conns >= peer->max_conns) {
+                continue;
+            }
+
             peer->current_weight += peer->effective_weight;
             total += peer->effective_weight;
 
@@ -296,6 +304,7 @@ ngx_http_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf->flags = NGX_HTTP_UPSTREAM_CREATE
                   |NGX_HTTP_UPSTREAM_WEIGHT
+                  |NGX_HTTP_UPSTREAM_MAX_CONNS
                   |NGX_HTTP_UPSTREAM_MAX_FAILS
                   |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
                   |NGX_HTTP_UPSTREAM_DOWN
index b8bf3f6561c0764665cc89c6a0fb476dbfd02d23..ceb798fecff151910f1792c54095bbee1c555567 100644 (file)
@@ -5444,6 +5444,7 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
 
     uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
                                          |NGX_HTTP_UPSTREAM_WEIGHT
+                                         |NGX_HTTP_UPSTREAM_MAX_CONNS
                                          |NGX_HTTP_UPSTREAM_MAX_FAILS
                                          |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
                                          |NGX_HTTP_UPSTREAM_DOWN
@@ -5545,7 +5546,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     time_t                       fail_timeout;
     ngx_str_t                   *value, s;
     ngx_url_t                    u;
-    ngx_int_t                    weight, max_fails;
+    ngx_int_t                    weight, max_conns, max_fails;
     ngx_uint_t                   i;
     ngx_http_upstream_server_t  *us;
 
@@ -5559,6 +5560,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     value = cf->args->elts;
 
     weight = 1;
+    max_conns = 0;
     max_fails = 1;
     fail_timeout = 10;
 
@@ -5579,6 +5581,21 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             continue;
         }
 
+        if (ngx_strncmp(value[i].data, "max_conns=", 10) == 0) {
+
+            if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_CONNS)) {
+                goto not_supported;
+            }
+
+            max_conns = ngx_atoi(&value[i].data[10], value[i].len - 10);
+
+            if (max_conns == NGX_ERROR) {
+                goto invalid;
+            }
+
+            continue;
+        }
+
         if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
 
             if (!(uscf->flags & NGX_HTTP_UPSTREAM_MAX_FAILS)) {
@@ -5655,6 +5672,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     us->addrs = u.addrs;
     us->naddrs = u.naddrs;
     us->weight = weight;
+    us->max_conns = max_conns;
     us->max_fails = max_fails;
     us->fail_timeout = fail_timeout;
 
index 397c8d574a59f0a49ae66abf166f2a581f110b85..d5246d11782cd5e1bbe2d2064f2d68902c70d2e7 100644 (file)
@@ -95,6 +95,7 @@ typedef struct {
     ngx_addr_t                      *addrs;
     ngx_uint_t                       naddrs;
     ngx_uint_t                       weight;
+    ngx_uint_t                       max_conns;
     ngx_uint_t                       max_fails;
     time_t                           fail_timeout;
 
@@ -109,6 +110,7 @@ typedef struct {
 #define NGX_HTTP_UPSTREAM_FAIL_TIMEOUT  0x0008
 #define NGX_HTTP_UPSTREAM_DOWN          0x0010
 #define NGX_HTTP_UPSTREAM_BACKUP        0x0020
+#define NGX_HTTP_UPSTREAM_MAX_CONNS     0x0100
 
 
 struct ngx_http_upstream_srv_conf_s {
index 81564b3b3f332234e24129389e1e1d7b58b6be6b..501584d3722e8b663dbcd6e012c2f1522a2391de 100644 (file)
@@ -92,6 +92,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
                 peer[n].weight = server[i].weight;
                 peer[n].effective_weight = server[i].weight;
                 peer[n].current_weight = 0;
+                peer[n].max_conns = server[i].max_conns;
                 peer[n].max_fails = server[i].max_fails;
                 peer[n].fail_timeout = server[i].fail_timeout;
                 peer[n].down = server[i].down;
@@ -155,6 +156,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
                 peer[n].weight = server[i].weight;
                 peer[n].effective_weight = server[i].weight;
                 peer[n].current_weight = 0;
+                peer[n].max_conns = server[i].max_conns;
                 peer[n].max_fails = server[i].max_fails;
                 peer[n].fail_timeout = server[i].fail_timeout;
                 peer[n].down = server[i].down;
@@ -223,6 +225,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
         peer[i].weight = 1;
         peer[i].effective_weight = 1;
         peer[i].current_weight = 0;
+        peer[i].max_conns = 0;
         peer[i].max_fails = 1;
         peer[i].fail_timeout = 10;
         *peerp = &peer[i];
@@ -337,6 +340,7 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
         peer[0].weight = 1;
         peer[0].effective_weight = 1;
         peer[0].current_weight = 0;
+        peer[0].max_conns = 0;
         peer[0].max_fails = 1;
         peer[0].fail_timeout = 10;
         peers->peer = peer;
@@ -370,6 +374,7 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
             peer[i].weight = 1;
             peer[i].effective_weight = 1;
             peer[i].current_weight = 0;
+            peer[i].max_conns = 0;
             peer[i].max_fails = 1;
             peer[i].fail_timeout = 10;
             *peerp = &peer[i];
@@ -432,6 +437,10 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
             goto failed;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            goto failed;
+        }
+
         rrp->current = peer;
 
     } else {
@@ -533,6 +542,10 @@ ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
             continue;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            continue;
+        }
+
         peer->current_weight += peer->effective_weight;
         total += peer->effective_weight;
 
index 355620add150abaad8118195d4926f2c7c442ca1..634fe539ea4843b7f65071f7b6f396c329e6292d 100644 (file)
@@ -27,6 +27,7 @@ struct ngx_http_upstream_rr_peer_s {
     ngx_int_t                       weight;
 
     ngx_uint_t                      conns;
+    ngx_uint_t                      max_conns;
 
     ngx_uint_t                      fails;
     time_t                          accessed;
index 2a164fc8c58cb312922462a71e10f5a766de8791..c9e17845e5bd2c59204be7923ae1c6369f90aa38 100644 (file)
@@ -322,6 +322,7 @@ ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
 
     uscf = ngx_stream_upstream_add(cf, &u, NGX_STREAM_UPSTREAM_CREATE
                                            |NGX_STREAM_UPSTREAM_WEIGHT
+                                           |NGX_STREAM_UPSTREAM_MAX_CONNS
                                            |NGX_STREAM_UPSTREAM_MAX_FAILS
                                            |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT
                                            |NGX_STREAM_UPSTREAM_DOWN
@@ -407,7 +408,7 @@ ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     time_t                         fail_timeout;
     ngx_str_t                     *value, s;
     ngx_url_t                      u;
-    ngx_int_t                      weight, max_fails;
+    ngx_int_t                      weight, max_conns, max_fails;
     ngx_uint_t                     i;
     ngx_stream_upstream_server_t  *us;
 
@@ -421,6 +422,7 @@ ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     value = cf->args->elts;
 
     weight = 1;
+    max_conns = 0;
     max_fails = 1;
     fail_timeout = 10;
 
@@ -441,6 +443,21 @@ ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
             continue;
         }
 
+        if (ngx_strncmp(value[i].data, "max_conns=", 10) == 0) {
+
+            if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_CONNS)) {
+                goto not_supported;
+            }
+
+            max_conns = ngx_atoi(&value[i].data[10], value[i].len - 10);
+
+            if (max_conns == NGX_ERROR) {
+                goto invalid;
+            }
+
+            continue;
+        }
+
         if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
 
             if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_FAILS)) {
@@ -522,6 +539,7 @@ ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     us->addrs = u.addrs;
     us->naddrs = u.naddrs;
     us->weight = weight;
+    us->max_conns = max_conns;
     us->max_fails = max_fails;
     us->fail_timeout = fail_timeout;
 
index 1e9f08fc63b8b7a36877efeec2cdb6f6ad90ad76..578ae00042800ba684c84bd3bab40a3ef6ab5c75 100644 (file)
@@ -21,6 +21,7 @@
 #define NGX_STREAM_UPSTREAM_FAIL_TIMEOUT  0x0008
 #define NGX_STREAM_UPSTREAM_DOWN          0x0010
 #define NGX_STREAM_UPSTREAM_BACKUP        0x0020
+#define NGX_STREAM_UPSTREAM_MAX_CONNS     0x0100
 
 
 typedef struct {
@@ -50,6 +51,7 @@ typedef struct {
     ngx_addr_t                        *addrs;
     ngx_uint_t                         naddrs;
     ngx_uint_t                         weight;
+    ngx_uint_t                         max_conns;
     ngx_uint_t                         max_fails;
     time_t                             fail_timeout;
 
index 0952f330a6181e5aa5890378b12e87176aec2550..cb44fcdad6f0665192a02e8002ad2142efc7917b 100644 (file)
@@ -241,6 +241,10 @@ ngx_stream_upstream_get_hash_peer(ngx_peer_connection_t *pc, void *data)
             goto next;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            goto next;
+        }
+
         break;
 
     next:
@@ -549,6 +553,10 @@ ngx_stream_upstream_get_chash_peer(ngx_peer_connection_t *pc, void *data)
                 continue;
             }
 
+            if (peer->max_conns && peer->conns >= peer->max_conns) {
+                continue;
+            }
+
             peer->current_weight += peer->effective_weight;
             total += peer->effective_weight;
 
@@ -646,6 +654,7 @@ ngx_stream_upstream_hash(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf->flags = NGX_STREAM_UPSTREAM_CREATE
                   |NGX_STREAM_UPSTREAM_WEIGHT
+                  |NGX_STREAM_UPSTREAM_MAX_CONNS
                   |NGX_STREAM_UPSTREAM_MAX_FAILS
                   |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT
                   |NGX_STREAM_UPSTREAM_DOWN;
index 1213bb53b408e95c2e4d7e498cb105ac143951b1..739b20a9f1eade53837bb19582144048a5c1a989 100644 (file)
@@ -150,6 +150,10 @@ ngx_stream_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
             continue;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            continue;
+        }
+
         /*
          * select peer with least number of connections; if there are
          * multiple peers with the same number of connections, select
@@ -205,6 +209,10 @@ ngx_stream_upstream_get_least_conn_peer(ngx_peer_connection_t *pc, void *data)
                 continue;
             }
 
+            if (peer->max_conns && peer->conns >= peer->max_conns) {
+                continue;
+            }
+
             peer->current_weight += peer->effective_weight;
             total += peer->effective_weight;
 
@@ -292,6 +300,7 @@ ngx_stream_upstream_least_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     uscf->flags = NGX_STREAM_UPSTREAM_CREATE
                   |NGX_STREAM_UPSTREAM_WEIGHT
+                  |NGX_STREAM_UPSTREAM_MAX_CONNS
                   |NGX_STREAM_UPSTREAM_MAX_FAILS
                   |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT
                   |NGX_STREAM_UPSTREAM_DOWN
index 768aaff4e48d9666769510f9b7c8b59cb005dbf5..3f4bfcfa559bae842029c6ce64954563e60f33b2 100644 (file)
@@ -96,6 +96,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
                 peer[n].weight = server[i].weight;
                 peer[n].effective_weight = server[i].weight;
                 peer[n].current_weight = 0;
+                peer[n].max_conns = server[i].max_conns;
                 peer[n].max_fails = server[i].max_fails;
                 peer[n].fail_timeout = server[i].fail_timeout;
                 peer[n].down = server[i].down;
@@ -159,6 +160,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
                 peer[n].weight = server[i].weight;
                 peer[n].effective_weight = server[i].weight;
                 peer[n].current_weight = 0;
+                peer[n].max_conns = server[i].max_conns;
                 peer[n].max_fails = server[i].max_fails;
                 peer[n].fail_timeout = server[i].fail_timeout;
                 peer[n].down = server[i].down;
@@ -227,6 +229,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
         peer[i].weight = 1;
         peer[i].effective_weight = 1;
         peer[i].current_weight = 0;
+        peer[i].max_conns = 0;
         peer[i].max_fails = 1;
         peer[i].fail_timeout = 10;
         *peerp = &peer[i];
@@ -438,6 +441,10 @@ ngx_stream_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
             goto failed;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            goto failed;
+        }
+
         rrp->current = peer;
 
     } else {
@@ -539,6 +546,10 @@ ngx_stream_upstream_get_peer(ngx_stream_upstream_rr_peer_data_t *rrp)
             continue;
         }
 
+        if (peer->max_conns && peer->conns >= peer->max_conns) {
+            continue;
+        }
+
         peer->current_weight += peer->effective_weight;
         total += peer->effective_weight;
 
index bdec0b826dd9cd8dfcc8c93d88c38637b9f95a14..3a1bf36d6396cedc820eeccb00afd95ab46063d4 100644 (file)
@@ -27,6 +27,7 @@ struct ngx_stream_upstream_rr_peer_s {
     ngx_int_t                        weight;
 
     ngx_uint_t                       conns;
+    ngx_uint_t                       max_conns;
 
     ngx_uint_t                       fails;
     time_t                           accessed;