Mercurial > hg > nginx-quic
annotate src/http/ngx_http_upstream_round_robin.c @ 4663:b9ea486e543f stable-1.2
Merge of r4617: fastcgi padding fix.
Fastcgi: fixed padding handling on fixed-size records.
Padding was incorrectly ignored on end request, empty stdout and stderr
fastcgi records. This resulted in protocol desynchronization if fastcgi
application used these records with padding for some reason.
Reported by Ilia Vinokurov.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 04 Jun 2012 11:00:34 +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 |