Mercurial > hg > nginx-quic
annotate src/http/ngx_http_upstream_round_robin.c @ 4605:92ca02d2eccb
Version bump.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 23 Apr 2012 12:54:14 +0000 |
parents | 1db899642518 |
children | c90801720a0c d05ab8793a69 |
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); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
15 static ngx_uint_t |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
16 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers); |
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; | |
1376
6ff8c0c1e194
"down" server caused endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1344
diff
changeset
|
83 peers->peer[n].weight = server[i].down ? 0 : server[i].weight; |
6ff8c0c1e194
"down" server caused endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1344
diff
changeset
|
84 peers->peer[n].current_weight = peers->peer[n].weight; |
884 | 85 n++; |
86 } | |
87 } | |
88 | |
89 us->peer.data = peers; | |
90 | |
1379 | 91 ngx_sort(&peers->peer[0], (size_t) n, |
92 sizeof(ngx_http_upstream_rr_peer_t), | |
93 ngx_http_upstream_cmp_servers); | |
94 | |
1378 | 95 /* backup servers */ |
96 | |
97 n = 0; | |
98 | |
99 for (i = 0; i < us->servers->nelts; i++) { | |
100 if (!server[i].backup) { | |
101 continue; | |
102 } | |
103 | |
104 n += server[i].naddrs; | |
105 } | |
106 | |
107 if (n == 0) { | |
108 return NGX_OK; | |
109 } | |
110 | |
111 backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
112 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
113 if (backup == NULL) { | |
114 return NGX_ERROR; | |
115 } | |
116 | |
117 peers->single = 0; | |
118 backup->single = 0; | |
119 backup->number = n; | |
120 backup->name = &us->host; | |
121 | |
122 n = 0; | |
123 | |
124 for (i = 0; i < us->servers->nelts; i++) { | |
125 for (j = 0; j < server[i].naddrs; j++) { | |
126 if (!server[i].backup) { | |
127 continue; | |
128 } | |
129 | |
130 backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
131 backup->peer[n].socklen = server[i].addrs[j].socklen; | |
132 backup->peer[n].name = server[i].addrs[j].name; | |
133 backup->peer[n].weight = server[i].weight; | |
134 backup->peer[n].current_weight = server[i].weight; | |
135 backup->peer[n].max_fails = server[i].max_fails; | |
136 backup->peer[n].fail_timeout = server[i].fail_timeout; | |
137 backup->peer[n].down = server[i].down; | |
138 n++; | |
139 } | |
140 } | |
141 | |
142 peers->next = backup; | |
143 | |
1379 | 144 ngx_sort(&backup->peer[0], (size_t) n, |
145 sizeof(ngx_http_upstream_rr_peer_t), | |
146 ngx_http_upstream_cmp_servers); | |
147 | |
884 | 148 return NGX_OK; |
149 } | |
150 | |
151 | |
152 /* an upstream implicitly defined by proxy_pass, etc. */ | |
153 | |
906 | 154 if (us->port == 0 && us->default_port == 0) { |
155 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
156 "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
|
157 &us->host, us->file_name, us->line); |
906 | 158 return NGX_ERROR; |
159 } | |
160 | |
884 | 161 ngx_memzero(&u, sizeof(ngx_url_t)); |
162 | |
163 u.host = us->host; | |
916 | 164 u.port = (in_port_t) (us->port ? us->port : us->default_port); |
884 | 165 |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1556
diff
changeset
|
166 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { |
884 | 167 if (u.err) { |
168 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
|
169 "%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
|
170 u.err, &us->host, us->file_name, us->line); |
884 | 171 } |
172 | |
173 return NGX_ERROR; | |
174 } | |
175 | |
176 n = u.naddrs; | |
177 | |
178 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
179 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
180 if (peers == NULL) { | |
181 return NGX_ERROR; | |
182 } | |
183 | |
1378 | 184 peers->single = (n == 1); |
884 | 185 peers->number = n; |
186 peers->name = &us->host; | |
187 | |
188 for (i = 0; i < u.naddrs; i++) { | |
1564 | 189 peers->peer[i].sockaddr = u.addrs[i].sockaddr; |
190 peers->peer[i].socklen = u.addrs[i].socklen; | |
191 peers->peer[i].name = u.addrs[i].name; | |
192 peers->peer[i].weight = 1; | |
193 peers->peer[i].current_weight = 1; | |
194 peers->peer[i].max_fails = 1; | |
195 peers->peer[i].fail_timeout = 10; | |
884 | 196 } |
197 | |
198 us->peer.data = peers; | |
199 | |
1378 | 200 /* implicitly defined upstream has no backup servers */ |
201 | |
884 | 202 return NGX_OK; |
203 } | |
204 | |
205 | |
1956
cb8c0c8e0c27
use ngx_int_t in ngx_sort() callback
Igor Sysoev <igor@sysoev.ru>
parents:
1887
diff
changeset
|
206 static ngx_int_t |
1379 | 207 ngx_http_upstream_cmp_servers(const void *one, const void *two) |
208 { | |
209 ngx_http_upstream_rr_peer_t *first, *second; | |
210 | |
211 first = (ngx_http_upstream_rr_peer_t *) one; | |
212 second = (ngx_http_upstream_rr_peer_t *) two; | |
213 | |
214 return (first->weight < second->weight); | |
215 } | |
216 | |
217 | |
884 | 218 ngx_int_t |
219 ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r, | |
220 ngx_http_upstream_srv_conf_t *us) | |
221 { | |
222 ngx_uint_t n; | |
223 ngx_http_upstream_rr_peer_data_t *rrp; | |
224 | |
225 rrp = r->upstream->peer.data; | |
226 | |
227 if (rrp == NULL) { | |
228 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); | |
229 if (rrp == NULL) { | |
230 return NGX_ERROR; | |
231 } | |
232 | |
233 r->upstream->peer.data = rrp; | |
234 } | |
235 | |
236 rrp->peers = us->peer.data; | |
237 rrp->current = 0; | |
238 | |
4011
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
239 n = rrp->peers->number; |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
240 |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
241 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
|
242 n = rrp->peers->next->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 |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
245 if (n <= 8 * sizeof(uintptr_t)) { |
884 | 246 rrp->tried = &rrp->data; |
247 rrp->data = 0; | |
248 | |
249 } else { | |
4011
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
250 n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t)); |
884 | 251 |
252 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
253 if (rrp->tried == NULL) { | |
254 return NGX_ERROR; | |
255 } | |
256 } | |
257 | |
258 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
259 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
260 r->upstream->peer.tries = rrp->peers->number; | |
261 #if (NGX_HTTP_SSL) | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
262 r->upstream->peer.set_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
263 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
|
264 r->upstream->peer.save_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
265 ngx_http_upstream_save_round_robin_peer_session; |
884 | 266 #endif |
267 | |
268 return NGX_OK; | |
269 } | |
270 | |
271 | |
272 ngx_int_t | |
1658 | 273 ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, |
274 ngx_http_upstream_resolved_t *ur) | |
275 { | |
276 u_char *p; | |
277 size_t len; | |
278 ngx_uint_t i, n; | |
279 struct sockaddr_in *sin; | |
280 ngx_http_upstream_rr_peers_t *peers; | |
281 ngx_http_upstream_rr_peer_data_t *rrp; | |
282 | |
283 rrp = r->upstream->peer.data; | |
284 | |
285 if (rrp == NULL) { | |
286 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); | |
287 if (rrp == NULL) { | |
288 return NGX_ERROR; | |
289 } | |
290 | |
291 r->upstream->peer.data = rrp; | |
292 } | |
293 | |
294 peers = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
295 + sizeof(ngx_http_upstream_rr_peer_t) * (ur->naddrs - 1)); | |
296 if (peers == NULL) { | |
297 return NGX_ERROR; | |
298 } | |
299 | |
300 peers->single = (ur->naddrs == 1); | |
301 peers->number = ur->naddrs; | |
302 peers->name = &ur->host; | |
303 | |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
304 if (ur->sockaddr) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
305 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
|
306 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
|
307 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
|
308 peers->peer[0].weight = 1; |
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].current_weight = 1; |
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].max_fails = 1; |
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].fail_timeout = 10; |
1658 | 312 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
313 } else { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
314 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
315 for (i = 0; i < ur->naddrs; i++) { |
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 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
|
318 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
319 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
|
320 if (p == NULL) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
321 return NGX_ERROR; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
322 } |
1658 | 323 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
324 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
|
325 len = ngx_sprintf(&p[len], ":%d", ur->port) - p; |
1658 | 326 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
327 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
|
328 if (sin == NULL) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
329 return NGX_ERROR; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
330 } |
1658 | 331 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
332 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
|
333 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
|
334 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
|
335 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
336 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
|
337 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
|
338 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
|
339 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
|
340 peers->peer[i].weight = 1; |
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].current_weight = 1; |
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].max_fails = 1; |
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].fail_timeout = 10; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
344 } |
1658 | 345 } |
346 | |
347 rrp->peers = peers; | |
348 rrp->current = 0; | |
349 | |
350 if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { | |
351 rrp->tried = &rrp->data; | |
352 rrp->data = 0; | |
353 | |
354 } else { | |
355 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) | |
356 / (8 * sizeof(uintptr_t)); | |
357 | |
358 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
359 if (rrp->tried == NULL) { | |
360 return NGX_ERROR; | |
361 } | |
362 } | |
363 | |
364 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
365 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
366 r->upstream->peer.tries = rrp->peers->number; | |
367 #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
|
368 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
|
369 r->upstream->peer.save_session = ngx_http_upstream_empty_save_session; |
1658 | 370 #endif |
371 | |
372 return NGX_OK; | |
373 } | |
374 | |
375 | |
376 ngx_int_t | |
884 | 377 ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) |
378 { | |
379 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
380 | |
1378 | 381 time_t now; |
382 uintptr_t m; | |
383 ngx_int_t rc; | |
384 ngx_uint_t i, n; | |
385 ngx_connection_t *c; | |
386 ngx_http_upstream_rr_peer_t *peer; | |
387 ngx_http_upstream_rr_peers_t *peers; | |
884 | 388 |
389 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
390 "get rr peer, try: %ui", pc->tries); | |
391 | |
392 now = ngx_time(); | |
393 | |
394 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
395 | |
396 if (rrp->peers->last_cached) { | |
397 | |
398 /* cached connection */ | |
399 | |
400 c = rrp->peers->cached[rrp->peers->last_cached]; | |
401 rrp->peers->last_cached--; | |
402 | |
403 /* ngx_unlock_mutex(ppr->peers->mutex); */ | |
404 | |
405 #if (NGX_THREADS) | |
406 c->read->lock = c->read->own_lock; | |
407 c->write->lock = c->write->own_lock; | |
408 #endif | |
409 | |
410 pc->connection = c; | |
411 pc->cached = 1; | |
412 | |
413 return NGX_OK; | |
414 } | |
415 | |
416 pc->cached = 0; | |
417 pc->connection = NULL; | |
418 | |
1378 | 419 if (rrp->peers->single) { |
884 | 420 peer = &rrp->peers->peer[0]; |
421 | |
422 } else { | |
423 | |
424 /* there are several peers */ | |
425 | |
426 if (pc->tries == rrp->peers->number) { | |
427 | |
428 /* it's a first try - get a current peer */ | |
429 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
430 i = pc->tries; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
431 |
884 | 432 for ( ;; ) { |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
433 rrp->current = ngx_http_upstream_get_peer(rrp->peers); |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
434 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
435 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
436 "get rr peer, current: %ui %i", |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
437 rrp->current, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
438 rrp->peers->peer[rrp->current].current_weight); |
884 | 439 |
440 n = rrp->current / (8 * sizeof(uintptr_t)); | |
1206
451e34738078
fix worker endless loop on 64-bit platform if 33+ backend has fall
Igor Sysoev <igor@sysoev.ru>
parents:
916
diff
changeset
|
441 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); |
884 | 442 |
443 if (!(rrp->tried[n] & m)) { | |
444 peer = &rrp->peers->peer[rrp->current]; | |
445 | |
446 if (!peer->down) { | |
447 | |
448 if (peer->max_fails == 0 | |
449 || peer->fails < peer->max_fails) | |
450 { | |
451 break; | |
452 } | |
453 | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
454 if (now - peer->checked > peer->fail_timeout) { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
455 peer->checked = now; |
884 | 456 break; |
457 } | |
458 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
459 peer->current_weight = 0; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
460 |
884 | 461 } else { |
462 rrp->tried[n] |= m; | |
463 } | |
464 | |
465 pc->tries--; | |
466 } | |
467 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
468 if (pc->tries == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
469 goto failed; |
884 | 470 } |
471 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
472 if (--i == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
473 ngx_log_error(NGX_LOG_ALERT, pc->log, 0, |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
474 "round robin upstream stuck on %ui tries", |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
475 pc->tries); |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
476 goto failed; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
477 } |
884 | 478 } |
479 | |
480 peer->current_weight--; | |
481 | |
482 } else { | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
483 |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
484 i = pc->tries; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
485 |
884 | 486 for ( ;; ) { |
487 n = rrp->current / (8 * sizeof(uintptr_t)); | |
1206
451e34738078
fix worker endless loop on 64-bit platform if 33+ backend has fall
Igor Sysoev <igor@sysoev.ru>
parents:
916
diff
changeset
|
488 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); |
884 | 489 |
490 if (!(rrp->tried[n] & m)) { | |
491 | |
492 peer = &rrp->peers->peer[rrp->current]; | |
493 | |
494 if (!peer->down) { | |
495 | |
496 if (peer->max_fails == 0 | |
497 || peer->fails < peer->max_fails) | |
498 { | |
499 break; | |
500 } | |
501 | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
502 if (now - peer->checked > peer->fail_timeout) { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
503 peer->checked = now; |
884 | 504 break; |
505 } | |
506 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
507 peer->current_weight = 0; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
508 |
884 | 509 } else { |
510 rrp->tried[n] |= m; | |
511 } | |
512 | |
513 pc->tries--; | |
514 } | |
515 | |
516 rrp->current++; | |
517 | |
518 if (rrp->current >= rrp->peers->number) { | |
519 rrp->current = 0; | |
520 } | |
521 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
522 if (pc->tries == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
523 goto failed; |
884 | 524 } |
525 | |
1419
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
526 if (--i == 0) { |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
527 ngx_log_error(NGX_LOG_ALERT, pc->log, 0, |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
528 "round robin upstream stuck on %ui tries", |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
529 pc->tries); |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
530 goto failed; |
79f033a89dd4
add guard code to prevent endless loop
Igor Sysoev <igor@sysoev.ru>
parents:
1389
diff
changeset
|
531 } |
884 | 532 } |
533 | |
534 peer->current_weight--; | |
535 } | |
536 | |
537 rrp->tried[n] |= m; | |
538 } | |
539 | |
540 pc->sockaddr = peer->sockaddr; | |
541 pc->socklen = peer->socklen; | |
542 pc->name = &peer->name; | |
543 | |
544 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
545 | |
1378 | 546 if (pc->tries == 1 && rrp->peers->next) { |
547 pc->tries += rrp->peers->next->number; | |
548 | |
549 n = rrp->peers->next->number / (8 * sizeof(uintptr_t)) + 1; | |
1389 | 550 for (i = 0; i < n; i++) { |
1378 | 551 rrp->tried[i] = 0; |
552 } | |
553 } | |
554 | |
884 | 555 return NGX_OK; |
556 | |
557 failed: | |
558 | |
1378 | 559 peers = rrp->peers; |
560 | |
561 if (peers->next) { | |
562 | |
563 /* ngx_unlock_mutex(peers->mutex); */ | |
564 | |
565 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers"); | |
566 | |
567 rrp->peers = peers->next; | |
568 pc->tries = rrp->peers->number; | |
569 | |
570 n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1; | |
1389 | 571 for (i = 0; i < n; i++) { |
1378 | 572 rrp->tried[i] = 0; |
573 } | |
574 | |
575 rc = ngx_http_upstream_get_round_robin_peer(pc, rrp); | |
576 | |
577 if (rc != NGX_BUSY) { | |
578 return rc; | |
579 } | |
580 | |
581 /* ngx_lock_mutex(peers->mutex); */ | |
582 } | |
583 | |
884 | 584 /* all peers failed, mark them as live for quick recovery */ |
585 | |
1378 | 586 for (i = 0; i < peers->number; i++) { |
587 peers->peer[i].fails = 0; | |
884 | 588 } |
589 | |
1378 | 590 /* ngx_unlock_mutex(peers->mutex); */ |
884 | 591 |
1378 | 592 pc->name = peers->name; |
884 | 593 |
594 return NGX_BUSY; | |
595 } | |
596 | |
597 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
598 static ngx_uint_t |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
599 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers) |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
600 { |
4010
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
601 ngx_uint_t i, n, reset = 0; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
602 ngx_http_upstream_rr_peer_t *peer; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
603 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
604 peer = &peers->peer[0]; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
605 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
606 for ( ;; ) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
607 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
608 for (i = 0; i < peers->number; i++) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
609 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
610 if (peer[i].current_weight <= 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
611 continue; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
612 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
613 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
614 n = i; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
615 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
616 while (i < peers->number - 1) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
617 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
618 i++; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
619 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
620 if (peer[i].current_weight <= 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
621 continue; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
622 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
623 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
624 if (peer[n].current_weight * 1000 / peer[i].current_weight |
1465
a9132739bb57
balance more fair when there are several servers with equal weights,
Igor Sysoev <igor@sysoev.ru>
parents:
1463
diff
changeset
|
625 > peer[n].weight * 1000 / peer[i].weight) |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
626 { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
627 return n; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
628 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
629 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
630 n = i; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
631 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
632 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
633 if (peer[i].current_weight > 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
634 n = i; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
635 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
636 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
637 return n; |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
638 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
639 |
4010
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
640 if (reset++) { |
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
641 return 0; |
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
642 } |
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
643 |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
644 for (i = 0; i < peers->number; i++) { |
1887
abbef7b5dab8
set absolute weight, this fixes bogus "no live upstream" case when
Igor Sysoev <igor@sysoev.ru>
parents:
1658
diff
changeset
|
645 peer[i].current_weight = peer[i].weight; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
646 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
647 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
648 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
649 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
650 |
884 | 651 void |
652 ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, | |
653 ngx_uint_t state) | |
654 { | |
655 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
656 | |
657 time_t now; | |
658 ngx_http_upstream_rr_peer_t *peer; | |
659 | |
660 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
661 "free rr peer %ui %ui", pc->tries, state); | |
662 | |
663 if (state == 0 && pc->tries == 0) { | |
664 return; | |
665 } | |
666 | |
667 /* TODO: NGX_PEER_KEEPALIVE */ | |
668 | |
1378 | 669 if (rrp->peers->single) { |
884 | 670 pc->tries = 0; |
671 return; | |
672 } | |
673 | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
674 peer = &rrp->peers->peer[rrp->current]; |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
675 |
884 | 676 if (state & NGX_PEER_FAILED) { |
677 now = ngx_time(); | |
678 | |
679 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
680 | |
681 peer->fails++; | |
682 peer->accessed = now; | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
683 peer->checked = now; |
884 | 684 |
2204
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
685 if (peer->max_fails) { |
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
686 peer->current_weight -= peer->weight / peer->max_fails; |
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
687 } |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
688 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
689 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
690 "free rr peer failed: %ui %i", |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
691 rrp->current, peer->current_weight); |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
692 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
693 if (peer->current_weight < 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
694 peer->current_weight = 0; |
884 | 695 } |
696 | |
697 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
698 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
699 } else { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
700 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
701 /* mark peer live if check passed */ |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
702 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
703 if (peer->accessed < peer->checked) { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
704 peer->fails = 0; |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
705 } |
884 | 706 } |
707 | |
708 rrp->current++; | |
709 | |
710 if (rrp->current >= rrp->peers->number) { | |
711 rrp->current = 0; | |
712 } | |
713 | |
714 if (pc->tries) { | |
715 pc->tries--; | |
716 } | |
717 | |
718 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
719 } | |
720 | |
721 | |
722 #if (NGX_HTTP_SSL) | |
723 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
724 ngx_int_t |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
725 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
|
726 void *data) |
884 | 727 { |
728 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
729 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
730 ngx_int_t rc; |
884 | 731 ngx_ssl_session_t *ssl_session; |
732 ngx_http_upstream_rr_peer_t *peer; | |
733 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
734 peer = &rrp->peers->peer[rrp->current]; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
735 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
736 /* TODO: threads only mutex */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
737 /* ngx_lock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
738 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
739 ssl_session = peer->ssl_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
740 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
741 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
|
742 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
743 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 744 "set session: %p:%d", |
745 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
|
746 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
747 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
748 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
749 return rc; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
750 } |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
751 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
752 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
753 void |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
754 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
|
755 void *data) |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
756 { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
757 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
|
758 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
759 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
|
760 ngx_http_upstream_rr_peer_t *peer; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
761 |
884 | 762 ssl_session = ngx_ssl_get_session(pc->connection); |
763 | |
764 if (ssl_session == NULL) { | |
765 return; | |
766 } | |
767 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
768 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 769 "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
|
770 |
884 | 771 peer = &rrp->peers->peer[rrp->current]; |
772 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
773 /* TODO: threads only mutex */ |
884 | 774 /* ngx_lock_mutex(rrp->peers->mutex); */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
775 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
776 old_ssl_session = peer->ssl_session; |
884 | 777 peer->ssl_session = ssl_session; |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
778 |
884 | 779 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
780 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
781 if (old_ssl_session) { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
782 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
783 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 784 "old session: %p:%d", |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
785 old_ssl_session, old_ssl_session->references); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
786 |
884 | 787 /* TODO: may block */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
788 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
789 ngx_ssl_free_session(old_ssl_session); |
884 | 790 } |
791 } | |
792 | |
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
|
793 |
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
|
794 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
|
795 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
|
796 { |
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
|
797 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
|
798 } |
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
|
799 |
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
|
800 |
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
|
801 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
|
802 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
|
803 { |
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
|
804 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
|
805 } |
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
|
806 |
884 | 807 #endif |