Klaus Demo nginx / 6876bcd
backup upstream servers Igor Sysoev 13 years ago
4 changed file(s) with 141 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
564564
565565 if (rc == NGX_BUSY) {
566566 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams");
567 }
568
569 if (rc == NGX_BUSY || rc == NGX_DECLINED) {
567 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE);
568 return;
569 }
570
571 if (rc == NGX_DECLINED) {
570572 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
571573 return;
572574 }
21522154 state = NGX_PEER_FAILED;
21532155 }
21542156
2155 u->peer.free(&u->peer, u->peer.data, state);
2157 if (ft_type != NGX_HTTP_UPSTREAM_FT_NOLIVE) {
2158 u->peer.free(&u->peer, u->peer.data, state);
2159 }
21562160
21572161 if (ft_type == NGX_HTTP_UPSTREAM_FT_TIMEOUT) {
21582162 ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ETIMEDOUT,
31173121 continue;
31183122 }
31193123
3124 if (ngx_strncmp(value[i].data, "backup", 6) == 0) {
3125
3126 if (!(uscf->flags & NGX_HTTP_UPSTREAM_BACKUP)) {
3127 goto invalid;
3128 }
3129
3130 us->backup = 1;
3131
3132 continue;
3133 }
3134
31203135 if (ngx_strncmp(value[i].data, "down", 4) == 0) {
31213136
31223137 if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
2323 #define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000040
2424 #define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000080
2525 #define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00000100
26 #define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000
2627 #define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000
2728
2829
1919 ngx_url_t u;
2020 ngx_uint_t i, j, n;
2121 ngx_http_upstream_server_t *server;
22 ngx_http_upstream_rr_peers_t *peers;
22 ngx_http_upstream_rr_peers_t *peers, *backup;
2323
2424 us->peer.init = ngx_http_upstream_init_round_robin_peer;
2525
2626 if (us->servers) {
27 server = us->servers->elts;
28
2729 n = 0;
28 server = us->servers->elts;
2930
3031 for (i = 0; i < us->servers->nelts; i++) {
32 if (server[i].backup) {
33 continue;
34 }
35
3136 n += server[i].naddrs;
3237 }
3338
3742 return NGX_ERROR;
3843 }
3944
45 peers->single = (n == 1);
4046 peers->number = n;
4147 peers->name = &us->host;
4248
4450
4551 for (i = 0; i < us->servers->nelts; i++) {
4652 for (j = 0; j < server[i].naddrs; j++) {
53 if (server[i].backup) {
54 continue;
55 }
56
4757 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;
4858 peers->peer[n].socklen = server[i].addrs[j].socklen;
4959 peers->peer[n].name = server[i].addrs[j].name;
5868
5969 us->peer.data = peers;
6070
71 /* backup servers */
72
73 n = 0;
74
75 for (i = 0; i < us->servers->nelts; i++) {
76 if (!server[i].backup) {
77 continue;
78 }
79
80 n += server[i].naddrs;
81 }
82
83 if (n == 0) {
84 return NGX_OK;
85 }
86
87 backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
88 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
89 if (backup == NULL) {
90 return NGX_ERROR;
91 }
92
93 peers->single = 0;
94 backup->single = 0;
95 backup->number = n;
96 backup->name = &us->host;
97
98 n = 0;
99
100 for (i = 0; i < us->servers->nelts; i++) {
101 for (j = 0; j < server[i].naddrs; j++) {
102 if (!server[i].backup) {
103 continue;
104 }
105
106 backup->peer[n].sockaddr = server[i].addrs[j].sockaddr;
107 backup->peer[n].socklen = server[i].addrs[j].socklen;
108 backup->peer[n].name = server[i].addrs[j].name;
109 backup->peer[n].weight = server[i].weight;
110 backup->peer[n].current_weight = server[i].weight;
111 backup->peer[n].max_fails = server[i].max_fails;
112 backup->peer[n].fail_timeout = server[i].fail_timeout;
113 backup->peer[n].down = server[i].down;
114 n++;
115 }
116 }
117
118 peers->next = backup;
119
61120 return NGX_OK;
62121 }
63122
94153 return NGX_ERROR;
95154 }
96155
156 peers->single = (n == 1);
97157 peers->number = n;
98158 peers->name = &us->host;
99159
112172
113173 us->peer.data = peers;
114174
175 /* implicitly defined upstream has no backup servers */
176
115177 return NGX_OK;
116178 }
117179
170232 {
171233 ngx_http_upstream_rr_peer_data_t *rrp = data;
172234
173 time_t now;
174 uintptr_t m;
175 ngx_uint_t i, n;
176 ngx_connection_t *c;
177 ngx_http_upstream_rr_peer_t *peer;
235 time_t now;
236 uintptr_t m;
237 ngx_int_t rc;
238 ngx_uint_t i, n;
239 ngx_connection_t *c;
240 ngx_http_upstream_rr_peer_t *peer;
241 ngx_http_upstream_rr_peers_t *peers;
178242
179243 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
180244 "get rr peer, try: %ui", pc->tries);
206270 pc->cached = 0;
207271 pc->connection = NULL;
208272
209 if (rrp->peers->number == 1) {
273 if (rrp->peers->single) {
210274 peer = &rrp->peers->peer[0];
211275
212276 } else {
318382
319383 /* ngx_unlock_mutex(rrp->peers->mutex); */
320384
385 if (pc->tries == 1 && rrp->peers->next) {
386 pc->tries += rrp->peers->next->number;
387
388 n = rrp->peers->next->number / (8 * sizeof(uintptr_t)) + 1;
389 for (i = 0; i < n; n++) {
390 rrp->tried[i] = 0;
391 }
392 }
393
321394 return NGX_OK;
322395
323396 failed:
324397
398 peers = rrp->peers;
399
400 if (peers->next) {
401
402 /* ngx_unlock_mutex(peers->mutex); */
403
404 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers");
405
406 rrp->peers = peers->next;
407 pc->tries = rrp->peers->number;
408
409 n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1;
410 for (i = 0; i < n; n++) {
411 rrp->tried[i] = 0;
412 }
413
414 rc = ngx_http_upstream_get_round_robin_peer(pc, rrp);
415
416 if (rc != NGX_BUSY) {
417 return rc;
418 }
419
420 /* ngx_lock_mutex(peers->mutex); */
421 }
422
325423 /* all peers failed, mark them as live for quick recovery */
326424
327 for (i = 0; i < rrp->peers->number; i++) {
328 rrp->peers->peer[i].fails = 0;
329 }
330
331 /* ngx_unlock_mutex(rrp->peers->mutex); */
332
333 pc->name = rrp->peers->name;
425 for (i = 0; i < peers->number; i++) {
426 peers->peer[i].fails = 0;
427 }
428
429 /* ngx_unlock_mutex(peers->mutex); */
430
431 pc->name = peers->name;
334432
335433 return NGX_BUSY;
336434 }
409507
410508 /* TODO: NGX_PEER_KEEPALIVE */
411509
412 if (rrp->peers->number == 1) {
510 if (rrp->peers->single) {
413511 pc->tries = 0;
414512 return;
415513 }
3434 } ngx_http_upstream_rr_peer_t;
3535
3636
37 typedef struct {
37 typedef struct ngx_http_upstream_rr_peers_s ngx_http_upstream_rr_peers_t;
38
39 struct ngx_http_upstream_rr_peers_s {
40 ngx_uint_t single; /* unsigned single:1; */
3841 ngx_uint_t number;
3942 ngx_uint_t last_cached;
4043
4346
4447 ngx_str_t *name;
4548
49 ngx_http_upstream_rr_peers_t *next;
50
4651 ngx_http_upstream_rr_peer_t peer[1];
47 } ngx_http_upstream_rr_peers_t;
52 };
4853
4954
5055 typedef struct {