comparison src/stream/ngx_stream_upstream_round_robin.c @ 7750:90cc7194e993

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).
author Ruslan Ermilov <ru@nginx.com>
date Fri, 27 Nov 2020 00:01:20 +0300
parents b99cbafd51da
children
comparison
equal deleted inserted replaced
7749:ac09a57ec50d 7750:90cc7194e993
8 #include <ngx_config.h> 8 #include <ngx_config.h>
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 #include <ngx_stream.h> 10 #include <ngx_stream.h>
11 11
12 12
13 #define ngx_stream_upstream_tries(p) ((p)->number \ 13 #define ngx_stream_upstream_tries(p) ((p)->tries \
14 + ((p)->next ? (p)->next->number : 0)) 14 + ((p)->next ? (p)->next->tries : 0))
15 15
16 16
17 static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer( 17 static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_get_peer(
18 ngx_stream_upstream_rr_peer_data_t *rrp); 18 ngx_stream_upstream_rr_peer_data_t *rrp);
19 static void ngx_stream_upstream_notify_round_robin_peer( 19 static void ngx_stream_upstream_notify_round_robin_peer(
36 ngx_int_t 36 ngx_int_t
37 ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, 37 ngx_stream_upstream_init_round_robin(ngx_conf_t *cf,
38 ngx_stream_upstream_srv_conf_t *us) 38 ngx_stream_upstream_srv_conf_t *us)
39 { 39 {
40 ngx_url_t u; 40 ngx_url_t u;
41 ngx_uint_t i, j, n, w; 41 ngx_uint_t i, j, n, w, t;
42 ngx_stream_upstream_server_t *server; 42 ngx_stream_upstream_server_t *server;
43 ngx_stream_upstream_rr_peer_t *peer, **peerp; 43 ngx_stream_upstream_rr_peer_t *peer, **peerp;
44 ngx_stream_upstream_rr_peers_t *peers, *backup; 44 ngx_stream_upstream_rr_peers_t *peers, *backup;
45 45
46 us->peer.init = ngx_stream_upstream_init_round_robin_peer; 46 us->peer.init = ngx_stream_upstream_init_round_robin_peer;
48 if (us->servers) { 48 if (us->servers) {
49 server = us->servers->elts; 49 server = us->servers->elts;
50 50
51 n = 0; 51 n = 0;
52 w = 0; 52 w = 0;
53 t = 0;
53 54
54 for (i = 0; i < us->servers->nelts; i++) { 55 for (i = 0; i < us->servers->nelts; i++) {
55 if (server[i].backup) { 56 if (server[i].backup) {
56 continue; 57 continue;
57 } 58 }
58 59
59 n += server[i].naddrs; 60 n += server[i].naddrs;
60 w += server[i].naddrs * server[i].weight; 61 w += server[i].naddrs * server[i].weight;
62
63 if (!server[i].down) {
64 t += server[i].naddrs;
65 }
61 } 66 }
62 67
63 if (n == 0) { 68 if (n == 0) {
64 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, 69 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
65 "no servers in upstream \"%V\" in %s:%ui", 70 "no servers in upstream \"%V\" in %s:%ui",
79 84
80 peers->single = (n == 1); 85 peers->single = (n == 1);
81 peers->number = n; 86 peers->number = n;
82 peers->weighted = (w != n); 87 peers->weighted = (w != n);
83 peers->total_weight = w; 88 peers->total_weight = w;
89 peers->tries = t;
84 peers->name = &us->host; 90 peers->name = &us->host;
85 91
86 n = 0; 92 n = 0;
87 peerp = &peers->peer; 93 peerp = &peers->peer;
88 94
114 120
115 /* backup servers */ 121 /* backup servers */
116 122
117 n = 0; 123 n = 0;
118 w = 0; 124 w = 0;
125 t = 0;
119 126
120 for (i = 0; i < us->servers->nelts; i++) { 127 for (i = 0; i < us->servers->nelts; i++) {
121 if (!server[i].backup) { 128 if (!server[i].backup) {
122 continue; 129 continue;
123 } 130 }
124 131
125 n += server[i].naddrs; 132 n += server[i].naddrs;
126 w += server[i].naddrs * server[i].weight; 133 w += server[i].naddrs * server[i].weight;
134
135 if (!server[i].down) {
136 t += server[i].naddrs;
137 }
127 } 138 }
128 139
129 if (n == 0) { 140 if (n == 0) {
130 return NGX_OK; 141 return NGX_OK;
131 } 142 }
143 peers->single = 0; 154 peers->single = 0;
144 backup->single = 0; 155 backup->single = 0;
145 backup->number = n; 156 backup->number = n;
146 backup->weighted = (w != n); 157 backup->weighted = (w != n);
147 backup->total_weight = w; 158 backup->total_weight = w;
159 backup->tries = t;
148 backup->name = &us->host; 160 backup->name = &us->host;
149 161
150 n = 0; 162 n = 0;
151 peerp = &backup->peer; 163 peerp = &backup->peer;
152 164
218 230
219 peers->single = (n == 1); 231 peers->single = (n == 1);
220 peers->number = n; 232 peers->number = n;
221 peers->weighted = 0; 233 peers->weighted = 0;
222 peers->total_weight = n; 234 peers->total_weight = n;
235 peers->tries = n;
223 peers->name = &us->host; 236 peers->name = &us->host;
224 237
225 peerp = &peers->peer; 238 peerp = &peers->peer;
226 239
227 for (i = 0; i < u.naddrs; i++) { 240 for (i = 0; i < u.naddrs; i++) {
340 return NGX_ERROR; 353 return NGX_ERROR;
341 } 354 }
342 355
343 peers->single = (ur->naddrs == 1); 356 peers->single = (ur->naddrs == 1);
344 peers->number = ur->naddrs; 357 peers->number = ur->naddrs;
358 peers->tries = ur->naddrs;
345 peers->name = &ur->host; 359 peers->name = &ur->host;
346 360
347 if (ur->sockaddr) { 361 if (ur->sockaddr) {
348 peer[0].sockaddr = ur->sockaddr; 362 peer[0].sockaddr = ur->sockaddr;
349 peer[0].socklen = ur->socklen; 363 peer[0].socklen = ur->socklen;