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) {