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