Mercurial > hg > nginx
annotate src/http/ngx_http_upstream_round_robin.c @ 4167:e917fc5eceb7 stable-1.0
Merging r4011, r4012, r4136:
Proxy related fixes:
*) Fixing cpu hog with all upstream servers marked "down".
The following configuration causes nginx to hog cpu due to infinite loop
in ngx_http_upstream_get_peer():
upstream backend {
server 127.0.0.1:8080 down;
server 127.0.0.1:8080 down;
}
server {
...
location / {
proxy_pass http://backend;
}
}
Make sure we don't loop infinitely in ngx_http_upstream_get_peer() but stop
after resetting peer weights once.
Return 0 if we are stuck. This is guaranteed to work as peer 0 always exists,
and eventually ngx_http_upstream_get_round_robin_peer() will do the right
thing falling back to backup servers or returning NGX_BUSY.
*) Upstream: properly allocate memory for tried flags.
Previous allocation only took into account number of non-backup servers, and
this caused memory corruption with many backup servers.
See report here:
http://mailman.nginx.org/pipermail/nginx/2011-May/026531.html
*) Fix of cpu hog in event pipe.
If client closed connection in ngx_event_pipe_write_to_downstream(), buffers
in the "out" chain were lost. This caused cpu hog if all available buffers
were in the "out" chain. Fix is to call ngx_chain_update_chains() before
checking return code of output filter to avoid loosing buffers in the "out"
chain.
Note that this situation (all available buffers in the "out" chain) isn't
normal, it should be prevented by busy buffers limit. Though right now it
may happen with complex protocols like fastcgi. This should be addressed
separately.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 30 Sep 2011 14:30:01 +0000 |
parents | f87edc142316 |
children | 4919fb357a5d |
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 |
4041
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
17 #if (NGX_HTTP_SSL) |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
18 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
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, |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
20 void *data); |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
21 static void ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
22 void *data); |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
23 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
24 #endif |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
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 | |
4167 | 231 n = rrp->peers->number; |
232 | |
233 if (rrp->peers->next && rrp->peers->next->number > n) { | |
234 n = rrp->peers->next->number; | |
235 } | |
236 | |
237 if (n <= 8 * sizeof(uintptr_t)) { | |
884 | 238 rrp->tried = &rrp->data; |
239 rrp->data = 0; | |
240 | |
241 } else { | |
4167 | 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) | |
4041
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
360 r->upstream->peer.set_session = ngx_http_upstream_empty_set_session; |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
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 | |
446 if (now - peer->accessed > peer->fail_timeout) { | |
447 peer->fails = 0; | |
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 | |
494 if (now - peer->accessed > peer->fail_timeout) { | |
495 peer->fails = 0; | |
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 { |
4167 | 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 |
4167 | 632 if (reset++) { |
633 return 0; | |
634 } | |
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 | |
666 if (state & NGX_PEER_FAILED) { | |
667 now = ngx_time(); | |
668 | |
669 peer = &rrp->peers->peer[rrp->current]; | |
670 | |
671 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
672 | |
673 peer->fails++; | |
674 peer->accessed = now; | |
675 | |
2204
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
676 if (peer->max_fails) { |
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
677 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
|
678 } |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
679 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
680 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
681 "free rr peer failed: %ui %i", |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
682 rrp->current, peer->current_weight); |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
683 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
684 if (peer->current_weight < 0) { |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
685 peer->current_weight = 0; |
884 | 686 } |
687 | |
688 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
689 } | |
690 | |
691 rrp->current++; | |
692 | |
693 if (rrp->current >= rrp->peers->number) { | |
694 rrp->current = 0; | |
695 } | |
696 | |
697 if (pc->tries) { | |
698 pc->tries--; | |
699 } | |
700 | |
701 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
702 } | |
703 | |
704 | |
705 #if (NGX_HTTP_SSL) | |
706 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
707 ngx_int_t |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
708 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
|
709 void *data) |
884 | 710 { |
711 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
712 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
713 ngx_int_t rc; |
884 | 714 ngx_ssl_session_t *ssl_session; |
715 ngx_http_upstream_rr_peer_t *peer; | |
716 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
717 peer = &rrp->peers->peer[rrp->current]; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
718 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
719 /* TODO: threads only mutex */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
720 /* ngx_lock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
721 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
722 ssl_session = peer->ssl_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
723 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
724 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
|
725 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
726 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 727 "set session: %p:%d", |
728 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
|
729 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
730 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
731 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
732 return rc; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
733 } |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
734 |
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 void |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
737 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
|
738 void *data) |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
739 { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
740 ngx_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
|
741 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
742 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
|
743 ngx_http_upstream_rr_peer_t *peer; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
744 |
884 | 745 ssl_session = ngx_ssl_get_session(pc->connection); |
746 | |
747 if (ssl_session == NULL) { | |
748 return; | |
749 } | |
750 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
751 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 752 "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
|
753 |
884 | 754 peer = &rrp->peers->peer[rrp->current]; |
755 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
756 /* TODO: threads only mutex */ |
884 | 757 /* ngx_lock_mutex(rrp->peers->mutex); */ |
1284
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 old_ssl_session = peer->ssl_session; |
884 | 760 peer->ssl_session = ssl_session; |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
761 |
884 | 762 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
763 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
764 if (old_ssl_session) { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
765 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
766 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 767 "old session: %p:%d", |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
768 old_ssl_session, old_ssl_session->references); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
769 |
884 | 770 /* TODO: may block */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
771 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
772 ngx_ssl_free_session(old_ssl_session); |
884 | 773 } |
774 } | |
775 | |
4041
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
776 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
777 static ngx_int_t |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
778 ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data) |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
779 { |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
780 return NGX_OK; |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
781 } |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
782 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
783 |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
784 static void |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
785 ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data) |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
786 { |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
787 return; |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
788 } |
f87edc142316
Merge of r3960, r3961, r3962, r3963, r3965:
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
789 |
884 | 790 #endif |