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