Mercurial > hg > nginx
annotate src/http/ngx_http_upstream_round_robin.c @ 4622:0dfdc3f732cb
Upstream: fixed ip_hash rebalancing with the "down" flag.
Due to weight being set to 0 for down peers, order of peers after sorting
wasn't the same as without the "down" flag (with down peers at the end),
resulting in client rebalancing for clients on other servers. The only
rebalancing which should happen after adding "down" to a server is one
for clients on the server.
The problem was introduced in r1377 (which fixed endless loop by setting
weight to 0 for down servers). The loop is no longer possible with new
smooth algorithm, so preserving original weight is safe.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 14 May 2012 09:58:07 +0000 |
parents | c90801720a0c |
children | 382c523d253a |
rev | line source |
---|---|
884 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
884 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
1956
cb8c0c8e0c27
use ngx_int_t in ngx_sort() callback
Igor Sysoev <igor@sysoev.ru>
parents:
1887
diff
changeset
|
13 static ngx_int_t ngx_http_upstream_cmp_servers(const void *one, |
cb8c0c8e0c27
use ngx_int_t in ngx_sort() callback
Igor Sysoev <igor@sysoev.ru>
parents:
1887
diff
changeset
|
14 const void *two); |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
15 static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer( |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
16 ngx_http_upstream_rr_peer_data_t *rrp); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
17 |
3964
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
18 #if (NGX_HTTP_SSL) |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
19 |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
20 static ngx_int_t ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
21 void *data); |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
22 static void ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
23 void *data); |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
24 |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
25 #endif |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
26 |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
27 |
884 | 28 ngx_int_t |
29 ngx_http_upstream_init_round_robin(ngx_conf_t *cf, | |
30 ngx_http_upstream_srv_conf_t *us) | |
31 { | |
32 ngx_url_t u; | |
33 ngx_uint_t i, j, n; | |
34 ngx_http_upstream_server_t *server; | |
1378 | 35 ngx_http_upstream_rr_peers_t *peers, *backup; |
884 | 36 |
37 us->peer.init = ngx_http_upstream_init_round_robin_peer; | |
38 | |
39 if (us->servers) { | |
40 server = us->servers->elts; | |
41 | |
1378 | 42 n = 0; |
43 | |
884 | 44 for (i = 0; i < us->servers->nelts; i++) { |
1378 | 45 if (server[i].backup) { |
46 continue; | |
47 } | |
48 | |
884 | 49 n += server[i].naddrs; |
50 } | |
51 | |
4569
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
52 if (n == 0) { |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
53 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
54 "no servers in upstream \"%V\" in %s:%ui", |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
55 &us->host, us->file_name, us->line); |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
56 return NGX_ERROR; |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
57 } |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
58 |
884 | 59 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) |
60 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
61 if (peers == NULL) { | |
62 return NGX_ERROR; | |
63 } | |
64 | |
1378 | 65 peers->single = (n == 1); |
884 | 66 peers->number = n; |
67 peers->name = &us->host; | |
68 | |
69 n = 0; | |
70 | |
71 for (i = 0; i < us->servers->nelts; i++) { | |
72 for (j = 0; j < server[i].naddrs; j++) { | |
1378 | 73 if (server[i].backup) { |
74 continue; | |
75 } | |
76 | |
884 | 77 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; |
78 peers->peer[n].socklen = server[i].addrs[j].socklen; | |
79 peers->peer[n].name = server[i].addrs[j].name; | |
80 peers->peer[n].max_fails = server[i].max_fails; | |
81 peers->peer[n].fail_timeout = server[i].fail_timeout; | |
82 peers->peer[n].down = server[i].down; | |
4622
0dfdc3f732cb
Upstream: fixed ip_hash rebalancing with the "down" flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4621
diff
changeset
|
83 peers->peer[n].weight = server[i].weight; |
0dfdc3f732cb
Upstream: fixed ip_hash rebalancing with the "down" flag.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4621
diff
changeset
|
84 peers->peer[n].effective_weight = server[i].weight; |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
85 peers->peer[n].current_weight = 0; |
884 | 86 n++; |
87 } | |
88 } | |
89 | |
90 us->peer.data = peers; | |
91 | |
1379 | 92 ngx_sort(&peers->peer[0], (size_t) n, |
93 sizeof(ngx_http_upstream_rr_peer_t), | |
94 ngx_http_upstream_cmp_servers); | |
95 | |
1378 | 96 /* backup servers */ |
97 | |
98 n = 0; | |
99 | |
100 for (i = 0; i < us->servers->nelts; i++) { | |
101 if (!server[i].backup) { | |
102 continue; | |
103 } | |
104 | |
105 n += server[i].naddrs; | |
106 } | |
107 | |
108 if (n == 0) { | |
109 return NGX_OK; | |
110 } | |
111 | |
112 backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
113 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
114 if (backup == NULL) { | |
115 return NGX_ERROR; | |
116 } | |
117 | |
118 peers->single = 0; | |
119 backup->single = 0; | |
120 backup->number = n; | |
121 backup->name = &us->host; | |
122 | |
123 n = 0; | |
124 | |
125 for (i = 0; i < us->servers->nelts; i++) { | |
126 for (j = 0; j < server[i].naddrs; j++) { | |
127 if (!server[i].backup) { | |
128 continue; | |
129 } | |
130 | |
131 backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
132 backup->peer[n].socklen = server[i].addrs[j].socklen; | |
133 backup->peer[n].name = server[i].addrs[j].name; | |
134 backup->peer[n].weight = server[i].weight; | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
135 backup->peer[n].effective_weight = server[i].weight; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
136 backup->peer[n].current_weight = 0; |
1378 | 137 backup->peer[n].max_fails = server[i].max_fails; |
138 backup->peer[n].fail_timeout = server[i].fail_timeout; | |
139 backup->peer[n].down = server[i].down; | |
140 n++; | |
141 } | |
142 } | |
143 | |
144 peers->next = backup; | |
145 | |
1379 | 146 ngx_sort(&backup->peer[0], (size_t) n, |
147 sizeof(ngx_http_upstream_rr_peer_t), | |
148 ngx_http_upstream_cmp_servers); | |
149 | |
884 | 150 return NGX_OK; |
151 } | |
152 | |
153 | |
154 /* an upstream implicitly defined by proxy_pass, etc. */ | |
155 | |
906 | 156 if (us->port == 0 && us->default_port == 0) { |
157 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
158 "no port in upstream \"%V\" in %s:%ui", | |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1465
diff
changeset
|
159 &us->host, us->file_name, us->line); |
906 | 160 return NGX_ERROR; |
161 } | |
162 | |
884 | 163 ngx_memzero(&u, sizeof(ngx_url_t)); |
164 | |
165 u.host = us->host; | |
916 | 166 u.port = (in_port_t) (us->port ? us->port : us->default_port); |
884 | 167 |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1556
diff
changeset
|
168 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { |
884 | 169 if (u.err) { |
170 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
896
f247db60fc85
fix fastcgi and memcached upstreams
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
171 "%s in upstream \"%V\" in %s:%ui", |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1465
diff
changeset
|
172 u.err, &us->host, us->file_name, us->line); |
884 | 173 } |
174 | |
175 return NGX_ERROR; | |
176 } | |
177 | |
178 n = u.naddrs; | |
179 | |
180 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
181 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
182 if (peers == NULL) { | |
183 return NGX_ERROR; | |
184 } | |
185 | |
1378 | 186 peers->single = (n == 1); |
884 | 187 peers->number = n; |
188 peers->name = &us->host; | |
189 | |
190 for (i = 0; i < u.naddrs; i++) { | |
1564 | 191 peers->peer[i].sockaddr = u.addrs[i].sockaddr; |
192 peers->peer[i].socklen = u.addrs[i].socklen; | |
193 peers->peer[i].name = u.addrs[i].name; | |
194 peers->peer[i].weight = 1; | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
195 peers->peer[i].effective_weight = 1; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
196 peers->peer[i].current_weight = 0; |
1564 | 197 peers->peer[i].max_fails = 1; |
198 peers->peer[i].fail_timeout = 10; | |
884 | 199 } |
200 | |
201 us->peer.data = peers; | |
202 | |
1378 | 203 /* implicitly defined upstream has no backup servers */ |
204 | |
884 | 205 return NGX_OK; |
206 } | |
207 | |
208 | |
1956
cb8c0c8e0c27
use ngx_int_t in ngx_sort() callback
Igor Sysoev <igor@sysoev.ru>
parents:
1887
diff
changeset
|
209 static ngx_int_t |
1379 | 210 ngx_http_upstream_cmp_servers(const void *one, const void *two) |
211 { | |
212 ngx_http_upstream_rr_peer_t *first, *second; | |
213 | |
214 first = (ngx_http_upstream_rr_peer_t *) one; | |
215 second = (ngx_http_upstream_rr_peer_t *) two; | |
216 | |
217 return (first->weight < second->weight); | |
218 } | |
219 | |
220 | |
884 | 221 ngx_int_t |
222 ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r, | |
223 ngx_http_upstream_srv_conf_t *us) | |
224 { | |
225 ngx_uint_t n; | |
226 ngx_http_upstream_rr_peer_data_t *rrp; | |
227 | |
228 rrp = r->upstream->peer.data; | |
229 | |
230 if (rrp == NULL) { | |
231 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); | |
232 if (rrp == NULL) { | |
233 return NGX_ERROR; | |
234 } | |
235 | |
236 r->upstream->peer.data = rrp; | |
237 } | |
238 | |
239 rrp->peers = us->peer.data; | |
240 rrp->current = 0; | |
241 | |
4011
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
242 n = rrp->peers->number; |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
243 |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
244 if (rrp->peers->next && rrp->peers->next->number > n) { |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
245 n = rrp->peers->next->number; |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
246 } |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
247 |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
248 if (n <= 8 * sizeof(uintptr_t)) { |
884 | 249 rrp->tried = &rrp->data; |
250 rrp->data = 0; | |
251 | |
252 } else { | |
4011
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
253 n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t)); |
884 | 254 |
255 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
256 if (rrp->tried == NULL) { | |
257 return NGX_ERROR; | |
258 } | |
259 } | |
260 | |
261 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
262 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
263 r->upstream->peer.tries = rrp->peers->number; | |
264 #if (NGX_HTTP_SSL) | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
265 r->upstream->peer.set_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
266 ngx_http_upstream_set_round_robin_peer_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
267 r->upstream->peer.save_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
268 ngx_http_upstream_save_round_robin_peer_session; |
884 | 269 #endif |
270 | |
271 return NGX_OK; | |
272 } | |
273 | |
274 | |
275 ngx_int_t | |
1658 | 276 ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, |
277 ngx_http_upstream_resolved_t *ur) | |
278 { | |
279 u_char *p; | |
280 size_t len; | |
281 ngx_uint_t i, n; | |
282 struct sockaddr_in *sin; | |
283 ngx_http_upstream_rr_peers_t *peers; | |
284 ngx_http_upstream_rr_peer_data_t *rrp; | |
285 | |
286 rrp = r->upstream->peer.data; | |
287 | |
288 if (rrp == NULL) { | |
289 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); | |
290 if (rrp == NULL) { | |
291 return NGX_ERROR; | |
292 } | |
293 | |
294 r->upstream->peer.data = rrp; | |
295 } | |
296 | |
297 peers = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
298 + sizeof(ngx_http_upstream_rr_peer_t) * (ur->naddrs - 1)); | |
299 if (peers == NULL) { | |
300 return NGX_ERROR; | |
301 } | |
302 | |
303 peers->single = (ur->naddrs == 1); | |
304 peers->number = ur->naddrs; | |
305 peers->name = &ur->host; | |
306 | |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
307 if (ur->sockaddr) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
308 peers->peer[0].sockaddr = ur->sockaddr; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
309 peers->peer[0].socklen = ur->socklen; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
310 peers->peer[0].name = ur->host; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
311 peers->peer[0].weight = 1; |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
312 peers->peer[0].effective_weight = 1; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
313 peers->peer[0].current_weight = 0; |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
314 peers->peer[0].max_fails = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
315 peers->peer[0].fail_timeout = 10; |
1658 | 316 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
317 } else { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
318 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
319 for (i = 0; i < ur->naddrs; i++) { |
1658 | 320 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
321 len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
322 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
323 p = ngx_pnalloc(r->pool, len); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
324 if (p == NULL) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
325 return NGX_ERROR; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
326 } |
1658 | 327 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
328 len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
329 len = ngx_sprintf(&p[len], ":%d", ur->port) - p; |
1658 | 330 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
331 sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
332 if (sin == NULL) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
333 return NGX_ERROR; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
334 } |
1658 | 335 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
336 sin->sin_family = AF_INET; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
337 sin->sin_port = htons(ur->port); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
338 sin->sin_addr.s_addr = ur->addrs[i]; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
339 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
340 peers->peer[i].sockaddr = (struct sockaddr *) sin; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
341 peers->peer[i].socklen = sizeof(struct sockaddr_in); |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
342 peers->peer[i].name.len = len; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
343 peers->peer[i].name.data = p; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
344 peers->peer[i].weight = 1; |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
345 peers->peer[i].effective_weight = 1; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
346 peers->peer[i].current_weight = 0; |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
347 peers->peer[i].max_fails = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
348 peers->peer[i].fail_timeout = 10; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
349 } |
1658 | 350 } |
351 | |
352 rrp->peers = peers; | |
353 rrp->current = 0; | |
354 | |
355 if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { | |
356 rrp->tried = &rrp->data; | |
357 rrp->data = 0; | |
358 | |
359 } else { | |
360 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) | |
361 / (8 * sizeof(uintptr_t)); | |
362 | |
363 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
364 if (rrp->tried == NULL) { | |
365 return NGX_ERROR; | |
366 } | |
367 } | |
368 | |
369 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
370 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
371 r->upstream->peer.tries = rrp->peers->number; | |
372 #if (NGX_HTTP_SSL) | |
3964
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
373 r->upstream->peer.set_session = ngx_http_upstream_empty_set_session; |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
374 r->upstream->peer.save_session = ngx_http_upstream_empty_save_session; |
1658 | 375 #endif |
376 | |
377 return NGX_OK; | |
378 } | |
379 | |
380 | |
381 ngx_int_t | |
884 | 382 ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) |
383 { | |
384 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
385 | |
1378 | 386 ngx_int_t rc; |
387 ngx_uint_t i, n; | |
388 ngx_connection_t *c; | |
389 ngx_http_upstream_rr_peer_t *peer; | |
390 ngx_http_upstream_rr_peers_t *peers; | |
884 | 391 |
392 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
393 "get rr peer, try: %ui", pc->tries); | |
394 | |
395 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
396 | |
397 if (rrp->peers->last_cached) { | |
398 | |
399 /* cached connection */ | |
400 | |
401 c = rrp->peers->cached[rrp->peers->last_cached]; | |
402 rrp->peers->last_cached--; | |
403 | |
404 /* ngx_unlock_mutex(ppr->peers->mutex); */ | |
405 | |
406 #if (NGX_THREADS) | |
407 c->read->lock = c->read->own_lock; | |
408 c->write->lock = c->write->own_lock; | |
409 #endif | |
410 | |
411 pc->connection = c; | |
412 pc->cached = 1; | |
413 | |
414 return NGX_OK; | |
415 } | |
416 | |
417 pc->cached = 0; | |
418 pc->connection = NULL; | |
419 | |
1378 | 420 if (rrp->peers->single) { |
884 | 421 peer = &rrp->peers->peer[0]; |
422 | |
423 } else { | |
424 | |
425 /* there are several peers */ | |
426 | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
427 peer = ngx_http_upstream_get_peer(rrp); |
884 | 428 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
429 if (peer == NULL) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
430 goto failed; |
884 | 431 } |
432 | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
433 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
434 "get rr peer, current: %ui %i", |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
435 rrp->current, peer->current_weight); |
884 | 436 } |
437 | |
438 pc->sockaddr = peer->sockaddr; | |
439 pc->socklen = peer->socklen; | |
440 pc->name = &peer->name; | |
441 | |
442 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
443 | |
1378 | 444 if (pc->tries == 1 && rrp->peers->next) { |
445 pc->tries += rrp->peers->next->number; | |
446 } | |
447 | |
884 | 448 return NGX_OK; |
449 | |
450 failed: | |
451 | |
1378 | 452 peers = rrp->peers; |
453 | |
454 if (peers->next) { | |
455 | |
456 /* ngx_unlock_mutex(peers->mutex); */ | |
457 | |
458 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers"); | |
459 | |
460 rrp->peers = peers->next; | |
461 pc->tries = rrp->peers->number; | |
462 | |
463 n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1; | |
1389 | 464 for (i = 0; i < n; i++) { |
1378 | 465 rrp->tried[i] = 0; |
466 } | |
467 | |
468 rc = ngx_http_upstream_get_round_robin_peer(pc, rrp); | |
469 | |
470 if (rc != NGX_BUSY) { | |
471 return rc; | |
472 } | |
473 | |
474 /* ngx_lock_mutex(peers->mutex); */ | |
475 } | |
476 | |
884 | 477 /* all peers failed, mark them as live for quick recovery */ |
478 | |
1378 | 479 for (i = 0; i < peers->number; i++) { |
480 peers->peer[i].fails = 0; | |
884 | 481 } |
482 | |
1378 | 483 /* ngx_unlock_mutex(peers->mutex); */ |
884 | 484 |
1378 | 485 pc->name = peers->name; |
884 | 486 |
487 return NGX_BUSY; | |
488 } | |
489 | |
490 | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
491 static ngx_http_upstream_rr_peer_t * |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
492 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp) |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
493 { |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
494 time_t now; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
495 uintptr_t m; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
496 ngx_int_t total; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
497 ngx_uint_t i, n; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
498 ngx_http_upstream_rr_peer_t *peer, *best; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
499 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
500 now = ngx_time(); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
501 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
502 best = NULL; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
503 total = 0; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
504 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
505 for (i = 0; i < rrp->peers->number; i++) { |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
506 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
507 n = i / (8 * sizeof(uintptr_t)); |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
508 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
509 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
510 if (rrp->tried[n] & m) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
511 continue; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
512 } |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
513 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
514 peer = &rrp->peers->peer[i]; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
515 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
516 if (peer->down) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
517 continue; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
518 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
519 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
520 if (peer->max_fails |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
521 && peer->fails >= peer->max_fails |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
522 && now - peer->checked <= peer->fail_timeout) |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
523 { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
524 continue; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
525 } |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
526 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
527 peer->current_weight += peer->effective_weight; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
528 total += peer->effective_weight; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
529 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
530 if (peer->effective_weight < peer->weight) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
531 peer->effective_weight++; |
4010
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
532 } |
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
533 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
534 if (best == NULL || peer->current_weight > best->current_weight) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
535 best = peer; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
536 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
537 } |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
538 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
539 if (best == NULL) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
540 return NULL; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
541 } |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
542 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
543 i = best - &rrp->peers->peer[0]; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
544 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
545 rrp->current = i; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
546 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
547 n = i / (8 * sizeof(uintptr_t)); |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
548 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
549 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
550 rrp->tried[n] |= m; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
551 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
552 best->current_weight -= total; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
553 best->checked = now; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
554 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
555 return best; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
556 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
557 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
558 |
884 | 559 void |
560 ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, | |
561 ngx_uint_t state) | |
562 { | |
563 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
564 | |
565 time_t now; | |
566 ngx_http_upstream_rr_peer_t *peer; | |
567 | |
568 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
569 "free rr peer %ui %ui", pc->tries, state); | |
570 | |
571 if (state == 0 && pc->tries == 0) { | |
572 return; | |
573 } | |
574 | |
575 /* TODO: NGX_PEER_KEEPALIVE */ | |
576 | |
1378 | 577 if (rrp->peers->single) { |
884 | 578 pc->tries = 0; |
579 return; | |
580 } | |
581 | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
582 peer = &rrp->peers->peer[rrp->current]; |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
583 |
884 | 584 if (state & NGX_PEER_FAILED) { |
585 now = ngx_time(); | |
586 | |
587 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
588 | |
589 peer->fails++; | |
590 peer->accessed = now; | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
591 peer->checked = now; |
884 | 592 |
2204
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
593 if (peer->max_fails) { |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
594 peer->effective_weight -= peer->weight / peer->max_fails; |
2204
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
595 } |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
596 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
597 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
598 "free rr peer failed: %ui %i", |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
599 rrp->current, peer->effective_weight); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
600 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
601 if (peer->effective_weight < 0) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
602 peer->effective_weight = 0; |
884 | 603 } |
604 | |
605 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
606 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
607 } else { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
608 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
609 /* mark peer live if check passed */ |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
610 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
611 if (peer->accessed < peer->checked) { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
612 peer->fails = 0; |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
613 } |
884 | 614 } |
615 | |
616 if (pc->tries) { | |
617 pc->tries--; | |
618 } | |
619 | |
620 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
621 } | |
622 | |
623 | |
624 #if (NGX_HTTP_SSL) | |
625 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
626 ngx_int_t |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
627 ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc, |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
628 void *data) |
884 | 629 { |
630 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
631 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
632 ngx_int_t rc; |
884 | 633 ngx_ssl_session_t *ssl_session; |
634 ngx_http_upstream_rr_peer_t *peer; | |
635 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
636 peer = &rrp->peers->peer[rrp->current]; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
637 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
638 /* TODO: threads only mutex */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
639 /* ngx_lock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
640 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
641 ssl_session = peer->ssl_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
642 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
643 rc = ngx_ssl_set_session(pc->connection, ssl_session); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
644 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
645 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 646 "set session: %p:%d", |
647 ssl_session, ssl_session ? ssl_session->references : 0); | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
648 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
649 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
650 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
651 return rc; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
652 } |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
653 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
654 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
655 void |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
656 ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc, |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
657 void *data) |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
658 { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
659 ngx_http_upstream_rr_peer_data_t *rrp = data; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
660 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
661 ngx_ssl_session_t *old_ssl_session, *ssl_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
662 ngx_http_upstream_rr_peer_t *peer; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
663 |
884 | 664 ssl_session = ngx_ssl_get_session(pc->connection); |
665 | |
666 if (ssl_session == NULL) { | |
667 return; | |
668 } | |
669 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
670 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 671 "save session: %p:%d", ssl_session, ssl_session->references); |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
672 |
884 | 673 peer = &rrp->peers->peer[rrp->current]; |
674 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
675 /* TODO: threads only mutex */ |
884 | 676 /* ngx_lock_mutex(rrp->peers->mutex); */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
677 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
678 old_ssl_session = peer->ssl_session; |
884 | 679 peer->ssl_session = ssl_session; |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
680 |
884 | 681 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
682 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
683 if (old_ssl_session) { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
684 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
685 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 686 "old session: %p:%d", |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
687 old_ssl_session, old_ssl_session->references); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
688 |
884 | 689 /* TODO: may block */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
690 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
691 ngx_ssl_free_session(old_ssl_session); |
884 | 692 } |
693 } | |
694 | |
3964
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
695 |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
696 static ngx_int_t |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
697 ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data) |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
698 { |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
699 return NGX_OK; |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
700 } |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
701 |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
702 |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
703 static void |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
704 ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data) |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
705 { |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
706 return; |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
707 } |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
708 |
884 | 709 #endif |