# HG changeset patch # User Ruslan Ermilov # Date 1474561967 -10800 # Node ID 29bf0dbc0a77914bc94bd001a2b17d364e8e50d9 # Parent a44ba757851d595f300cc36de2263e569723d79d Upstream: max_conns. diff --git a/src/http/modules/ngx_http_upstream_hash_module.c b/src/http/modules/ngx_http_upstream_hash_module.c --- a/src/http/modules/ngx_http_upstream_hash_module.c +++ b/src/http/modules/ngx_http_upstream_hash_module.c @@ -242,6 +242,10 @@ ngx_http_upstream_get_hash_peer(ngx_peer 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_pee 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, n 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; diff --git a/src/http/modules/ngx_http_upstream_ip_hash_module.c b/src/http/modules/ngx_http_upstream_ip_hash_module.c --- a/src/http/modules/ngx_http_upstream_ip_hash_module.c +++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c @@ -212,6 +212,10 @@ ngx_http_upstream_get_ip_hash_peer(ngx_p 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 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; diff --git a/src/http/modules/ngx_http_upstream_least_conn_module.c b/src/http/modules/ngx_http_upstream_least_conn_module.c --- a/src/http/modules/ngx_http_upstream_least_conn_module.c +++ b/src/http/modules/ngx_http_upstream_least_conn_module.c @@ -154,6 +154,10 @@ ngx_http_upstream_get_least_conn_peer(ng 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(ng 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 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 diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -5444,6 +5444,7 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_co 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, 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, 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, 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, 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; diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h +++ b/src/http/ngx_http_upstream.h @@ -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 { diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c +++ b/src/http/ngx_http_upstream_round_robin.c @@ -92,6 +92,7 @@ ngx_http_upstream_init_round_robin(ngx_c 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_c 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_c 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_pee 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_pee 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(n 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_upst continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h --- a/src/http/ngx_http_upstream_round_robin.h +++ b/src/http/ngx_http_upstream_round_robin.h @@ -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; diff --git a/src/stream/ngx_stream_upstream.c b/src/stream/ngx_stream_upstream.c --- a/src/stream/ngx_stream_upstream.c +++ b/src/stream/ngx_stream_upstream.c @@ -322,6 +322,7 @@ ngx_stream_upstream(ngx_conf_t *cf, ngx_ 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 *c 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 *c 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 *c 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 *c 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; diff --git a/src/stream/ngx_stream_upstream.h b/src/stream/ngx_stream_upstream.h --- a/src/stream/ngx_stream_upstream.h +++ b/src/stream/ngx_stream_upstream.h @@ -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; diff --git a/src/stream/ngx_stream_upstream_hash_module.c b/src/stream/ngx_stream_upstream_hash_module.c --- a/src/stream/ngx_stream_upstream_hash_module.c +++ b/src/stream/ngx_stream_upstream_hash_module.c @@ -241,6 +241,10 @@ ngx_stream_upstream_get_hash_peer(ngx_pe 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_p 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, 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; diff --git a/src/stream/ngx_stream_upstream_least_conn_module.c b/src/stream/ngx_stream_upstream_least_conn_module.c --- a/src/stream/ngx_stream_upstream_least_conn_module.c +++ b/src/stream/ngx_stream_upstream_least_conn_module.c @@ -150,6 +150,10 @@ ngx_stream_upstream_get_least_conn_peer( 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( 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_ 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 diff --git a/src/stream/ngx_stream_upstream_round_robin.c b/src/stream/ngx_stream_upstream_round_robin.c --- a/src/stream/ngx_stream_upstream_round_robin.c +++ b/src/stream/ngx_stream_upstream_round_robin.c @@ -96,6 +96,7 @@ ngx_stream_upstream_init_round_robin(ngx 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 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 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 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_ continue; } + if (peer->max_conns && peer->conns >= peer->max_conns) { + continue; + } + peer->current_weight += peer->effective_weight; total += peer->effective_weight; diff --git a/src/stream/ngx_stream_upstream_round_robin.h b/src/stream/ngx_stream_upstream_round_robin.h --- a/src/stream/ngx_stream_upstream_round_robin.h +++ b/src/stream/ngx_stream_upstream_round_robin.h @@ -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;