Mercurial > hg > nginx-quic
comparison src/http/ngx_http_upstream_round_robin.c @ 1378:0be898896d1a
backup upstream servers
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 09 Aug 2007 13:54:33 +0000 |
parents | 6ff8c0c1e194 |
children | cc8ac1936aa4 |
comparison
equal
deleted
inserted
replaced
1377:0d57c150115b | 1378:0be898896d1a |
---|---|
18 ngx_http_upstream_srv_conf_t *us) | 18 ngx_http_upstream_srv_conf_t *us) |
19 { | 19 { |
20 ngx_url_t u; | 20 ngx_url_t u; |
21 ngx_uint_t i, j, n; | 21 ngx_uint_t i, j, n; |
22 ngx_http_upstream_server_t *server; | 22 ngx_http_upstream_server_t *server; |
23 ngx_http_upstream_rr_peers_t *peers; | 23 ngx_http_upstream_rr_peers_t *peers, *backup; |
24 | 24 |
25 us->peer.init = ngx_http_upstream_init_round_robin_peer; | 25 us->peer.init = ngx_http_upstream_init_round_robin_peer; |
26 | 26 |
27 if (us->servers) { | 27 if (us->servers) { |
28 server = us->servers->elts; | |
29 | |
28 n = 0; | 30 n = 0; |
29 server = us->servers->elts; | |
30 | 31 |
31 for (i = 0; i < us->servers->nelts; i++) { | 32 for (i = 0; i < us->servers->nelts; i++) { |
33 if (server[i].backup) { | |
34 continue; | |
35 } | |
36 | |
32 n += server[i].naddrs; | 37 n += server[i].naddrs; |
33 } | 38 } |
34 | 39 |
35 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | 40 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) |
36 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | 41 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); |
37 if (peers == NULL) { | 42 if (peers == NULL) { |
38 return NGX_ERROR; | 43 return NGX_ERROR; |
39 } | 44 } |
40 | 45 |
46 peers->single = (n == 1); | |
41 peers->number = n; | 47 peers->number = n; |
42 peers->name = &us->host; | 48 peers->name = &us->host; |
43 | 49 |
44 n = 0; | 50 n = 0; |
45 | 51 |
46 for (i = 0; i < us->servers->nelts; i++) { | 52 for (i = 0; i < us->servers->nelts; i++) { |
47 for (j = 0; j < server[i].naddrs; j++) { | 53 for (j = 0; j < server[i].naddrs; j++) { |
54 if (server[i].backup) { | |
55 continue; | |
56 } | |
57 | |
48 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; | 58 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; |
49 peers->peer[n].socklen = server[i].addrs[j].socklen; | 59 peers->peer[n].socklen = server[i].addrs[j].socklen; |
50 peers->peer[n].name = server[i].addrs[j].name; | 60 peers->peer[n].name = server[i].addrs[j].name; |
51 peers->peer[n].max_fails = server[i].max_fails; | 61 peers->peer[n].max_fails = server[i].max_fails; |
52 peers->peer[n].fail_timeout = server[i].fail_timeout; | 62 peers->peer[n].fail_timeout = server[i].fail_timeout; |
57 } | 67 } |
58 } | 68 } |
59 | 69 |
60 us->peer.data = peers; | 70 us->peer.data = peers; |
61 | 71 |
72 /* backup servers */ | |
73 | |
74 n = 0; | |
75 | |
76 for (i = 0; i < us->servers->nelts; i++) { | |
77 if (!server[i].backup) { | |
78 continue; | |
79 } | |
80 | |
81 n += server[i].naddrs; | |
82 } | |
83 | |
84 if (n == 0) { | |
85 return NGX_OK; | |
86 } | |
87 | |
88 backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
89 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
90 if (backup == NULL) { | |
91 return NGX_ERROR; | |
92 } | |
93 | |
94 peers->single = 0; | |
95 backup->single = 0; | |
96 backup->number = n; | |
97 backup->name = &us->host; | |
98 | |
99 n = 0; | |
100 | |
101 for (i = 0; i < us->servers->nelts; i++) { | |
102 for (j = 0; j < server[i].naddrs; j++) { | |
103 if (!server[i].backup) { | |
104 continue; | |
105 } | |
106 | |
107 backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
108 backup->peer[n].socklen = server[i].addrs[j].socklen; | |
109 backup->peer[n].name = server[i].addrs[j].name; | |
110 backup->peer[n].weight = server[i].weight; | |
111 backup->peer[n].current_weight = server[i].weight; | |
112 backup->peer[n].max_fails = server[i].max_fails; | |
113 backup->peer[n].fail_timeout = server[i].fail_timeout; | |
114 backup->peer[n].down = server[i].down; | |
115 n++; | |
116 } | |
117 } | |
118 | |
119 peers->next = backup; | |
120 | |
62 return NGX_OK; | 121 return NGX_OK; |
63 } | 122 } |
64 | 123 |
65 | 124 |
66 /* an upstream implicitly defined by proxy_pass, etc. */ | 125 /* an upstream implicitly defined by proxy_pass, etc. */ |
93 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | 152 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); |
94 if (peers == NULL) { | 153 if (peers == NULL) { |
95 return NGX_ERROR; | 154 return NGX_ERROR; |
96 } | 155 } |
97 | 156 |
157 peers->single = (n == 1); | |
98 peers->number = n; | 158 peers->number = n; |
99 peers->name = &us->host; | 159 peers->name = &us->host; |
100 | 160 |
101 n = 0; | 161 n = 0; |
102 | 162 |
111 n++; | 171 n++; |
112 } | 172 } |
113 | 173 |
114 us->peer.data = peers; | 174 us->peer.data = peers; |
115 | 175 |
176 /* implicitly defined upstream has no backup servers */ | |
177 | |
116 return NGX_OK; | 178 return NGX_OK; |
117 } | 179 } |
118 | 180 |
119 | 181 |
120 ngx_int_t | 182 ngx_int_t |
169 ngx_int_t | 231 ngx_int_t |
170 ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) | 232 ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) |
171 { | 233 { |
172 ngx_http_upstream_rr_peer_data_t *rrp = data; | 234 ngx_http_upstream_rr_peer_data_t *rrp = data; |
173 | 235 |
174 time_t now; | 236 time_t now; |
175 uintptr_t m; | 237 uintptr_t m; |
176 ngx_uint_t i, n; | 238 ngx_int_t rc; |
177 ngx_connection_t *c; | 239 ngx_uint_t i, n; |
178 ngx_http_upstream_rr_peer_t *peer; | 240 ngx_connection_t *c; |
241 ngx_http_upstream_rr_peer_t *peer; | |
242 ngx_http_upstream_rr_peers_t *peers; | |
179 | 243 |
180 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, | 244 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
181 "get rr peer, try: %ui", pc->tries); | 245 "get rr peer, try: %ui", pc->tries); |
182 | 246 |
183 now = ngx_time(); | 247 now = ngx_time(); |
205 } | 269 } |
206 | 270 |
207 pc->cached = 0; | 271 pc->cached = 0; |
208 pc->connection = NULL; | 272 pc->connection = NULL; |
209 | 273 |
210 if (rrp->peers->number == 1) { | 274 if (rrp->peers->single) { |
211 peer = &rrp->peers->peer[0]; | 275 peer = &rrp->peers->peer[0]; |
212 | 276 |
213 } else { | 277 } else { |
214 | 278 |
215 /* there are several peers */ | 279 /* there are several peers */ |
317 pc->socklen = peer->socklen; | 381 pc->socklen = peer->socklen; |
318 pc->name = &peer->name; | 382 pc->name = &peer->name; |
319 | 383 |
320 /* ngx_unlock_mutex(rrp->peers->mutex); */ | 384 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
321 | 385 |
386 if (pc->tries == 1 && rrp->peers->next) { | |
387 pc->tries += rrp->peers->next->number; | |
388 | |
389 n = rrp->peers->next->number / (8 * sizeof(uintptr_t)) + 1; | |
390 for (i = 0; i < n; n++) { | |
391 rrp->tried[i] = 0; | |
392 } | |
393 } | |
394 | |
322 return NGX_OK; | 395 return NGX_OK; |
323 | 396 |
324 failed: | 397 failed: |
325 | 398 |
399 peers = rrp->peers; | |
400 | |
401 if (peers->next) { | |
402 | |
403 /* ngx_unlock_mutex(peers->mutex); */ | |
404 | |
405 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers"); | |
406 | |
407 rrp->peers = peers->next; | |
408 pc->tries = rrp->peers->number; | |
409 | |
410 n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1; | |
411 for (i = 0; i < n; n++) { | |
412 rrp->tried[i] = 0; | |
413 } | |
414 | |
415 rc = ngx_http_upstream_get_round_robin_peer(pc, rrp); | |
416 | |
417 if (rc != NGX_BUSY) { | |
418 return rc; | |
419 } | |
420 | |
421 /* ngx_lock_mutex(peers->mutex); */ | |
422 } | |
423 | |
326 /* all peers failed, mark them as live for quick recovery */ | 424 /* all peers failed, mark them as live for quick recovery */ |
327 | 425 |
328 for (i = 0; i < rrp->peers->number; i++) { | 426 for (i = 0; i < peers->number; i++) { |
329 rrp->peers->peer[i].fails = 0; | 427 peers->peer[i].fails = 0; |
330 } | 428 } |
331 | 429 |
332 /* ngx_unlock_mutex(rrp->peers->mutex); */ | 430 /* ngx_unlock_mutex(peers->mutex); */ |
333 | 431 |
334 pc->name = rrp->peers->name; | 432 pc->name = peers->name; |
335 | 433 |
336 return NGX_BUSY; | 434 return NGX_BUSY; |
337 } | 435 } |
338 | 436 |
339 | 437 |
408 return; | 506 return; |
409 } | 507 } |
410 | 508 |
411 /* TODO: NGX_PEER_KEEPALIVE */ | 509 /* TODO: NGX_PEER_KEEPALIVE */ |
412 | 510 |
413 if (rrp->peers->number == 1) { | 511 if (rrp->peers->single) { |
414 pc->tries = 0; | 512 pc->tries = 0; |
415 return; | 513 return; |
416 } | 514 } |
417 | 515 |
418 if (state & NGX_PEER_FAILED) { | 516 if (state & NGX_PEER_FAILED) { |