From cfa669151e605410cfb57cc70b0e4023f4777602 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Fri, 27 Nov 2020 00:01:20 +0300 Subject: [PATCH] Upstream: excluded down servers from the next_upstream tries. Previously, the number of next_upstream tries included servers marked as "down", resulting in "no live upstreams" with the code 502 instead of the code derived from an attempt to connect to the last tried "up" server (ticket #2096). --- src/http/ngx_http_upstream_round_robin.c | 20 +++++++++++++++++--- src/http/ngx_http_upstream_round_robin.h | 1 + src/stream/ngx_stream_upstream_round_robin.c | 20 +++++++++++++++++--- src/stream/ngx_stream_upstream_round_robin.h | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c index 8e7b4ea8b..1f15fae50 100644 --- a/src/http/ngx_http_upstream_round_robin.c +++ b/src/http/ngx_http_upstream_round_robin.c @@ -10,8 +10,8 @@ #include -#define ngx_http_upstream_tries(p) ((p)->number \ - + ((p)->next ? (p)->next->number : 0)) +#define ngx_http_upstream_tries(p) ((p)->tries \ + + ((p)->next ? (p)->next->tries : 0)) static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer( @@ -32,7 +32,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { ngx_url_t u; - ngx_uint_t i, j, n, w; + ngx_uint_t i, j, n, w, t; ngx_http_upstream_server_t *server; ngx_http_upstream_rr_peer_t *peer, **peerp; ngx_http_upstream_rr_peers_t *peers, *backup; @@ -44,6 +44,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { @@ -52,6 +53,10 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -75,6 +80,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = (w != n); peers->total_weight = w; + peers->tries = t; peers->name = &us->host; n = 0; @@ -110,6 +116,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { @@ -118,6 +125,10 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -139,6 +150,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, backup->number = n; backup->weighted = (w != n); backup->total_weight = w; + backup->tries = t; backup->name = &us->host; n = 0; @@ -214,6 +226,7 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = 0; peers->total_weight = n; + peers->tries = n; peers->name = &us->host; peerp = &peers->peer; @@ -332,6 +345,7 @@ ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, peers->single = (ur->naddrs == 1); peers->number = ur->naddrs; + peers->tries = ur->naddrs; peers->name = &ur->host; if (ur->sockaddr) { diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h index 45f258d28..922ceaa04 100644 --- a/src/http/ngx_http_upstream_round_robin.h +++ b/src/http/ngx_http_upstream_round_robin.h @@ -68,6 +68,7 @@ struct ngx_http_upstream_rr_peers_s { #endif ngx_uint_t total_weight; + ngx_uint_t tries; unsigned single:1; unsigned weighted:1; diff --git a/src/stream/ngx_stream_upstream_round_robin.c b/src/stream/ngx_stream_upstream_round_robin.c index c2076673a..ae3bf37a6 100644 --- a/src/stream/ngx_stream_upstream_round_robin.c +++ b/src/stream/ngx_stream_upstream_round_robin.c @@ -10,8 +10,8 @@ #include -#define ngx_stream_upstream_tries(p) ((p)->number \ - + ((p)->next ? (p)->next->number : 0)) +#define ngx_stream_upstream_tries(p) ((p)->tries \ + + ((p)->next ? (p)->next->tries : 0)) static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer( @@ -38,7 +38,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, ngx_stream_upstream_srv_conf_t *us) { ngx_url_t u; - ngx_uint_t i, j, n, w; + ngx_uint_t i, j, n, w, t; ngx_stream_upstream_server_t *server; ngx_stream_upstream_rr_peer_t *peer, **peerp; ngx_stream_upstream_rr_peers_t *peers, *backup; @@ -50,6 +50,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { @@ -58,6 +59,10 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -81,6 +86,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = (w != n); peers->total_weight = w; + peers->tries = t; peers->name = &us->host; n = 0; @@ -116,6 +122,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n = 0; w = 0; + t = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { @@ -124,6 +131,10 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, n += server[i].naddrs; w += server[i].naddrs * server[i].weight; + + if (!server[i].down) { + t += server[i].naddrs; + } } if (n == 0) { @@ -145,6 +156,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, backup->number = n; backup->weighted = (w != n); backup->total_weight = w; + backup->tries = t; backup->name = &us->host; n = 0; @@ -220,6 +232,7 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, peers->number = n; peers->weighted = 0; peers->total_weight = n; + peers->tries = n; peers->name = &us->host; peerp = &peers->peer; @@ -342,6 +355,7 @@ ngx_stream_upstream_create_round_robin_peer(ngx_stream_session_t *s, peers->single = (ur->naddrs == 1); peers->number = ur->naddrs; + peers->tries = ur->naddrs; peers->name = &ur->host; if (ur->sockaddr) { diff --git a/src/stream/ngx_stream_upstream_round_robin.h b/src/stream/ngx_stream_upstream_round_robin.h index 35d9fce6c..bd96667ba 100644 --- a/src/stream/ngx_stream_upstream_round_robin.h +++ b/src/stream/ngx_stream_upstream_round_robin.h @@ -66,6 +66,7 @@ struct ngx_stream_upstream_rr_peers_s { #endif ngx_uint_t total_weight; + ngx_uint_t tries; unsigned single:1; unsigned weighted:1;