Mercurial > hg > nginx
annotate src/http/ngx_http_upstream_round_robin.c @ 5510:3ff29c30effb
SPDY: elimination of r->blocked counter usage for queuing frames.
It was used to prevent destroying of request object when there are unsent
frames in queue for the stream. Since it was incremented for each frame
and is only 8 bits long, so it was not very hard to overflow the counter.
Now the stream->queued counter is checked instead.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Tue, 14 Jan 2014 16:24:45 +0400 |
parents | 07dd5bd222ac |
children | efc84a5723b3 |
rev | line source |
---|---|
884 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
884 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
13 static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer( |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
14 ngx_http_upstream_rr_peer_data_t *rrp); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
15 |
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
|
16 #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
|
17 |
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 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
|
19 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
|
20 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
|
21 void *data); |
ff127ba3b091
do not try to reuse and save a SSL session for a peer created on the fly
Igor Sysoev <igor@sysoev.ru>
parents:
2422
diff
changeset
|
22 |
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 #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
|
24 |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
25 |
884 | 26 ngx_int_t |
27 ngx_http_upstream_init_round_robin(ngx_conf_t *cf, | |
28 ngx_http_upstream_srv_conf_t *us) | |
29 { | |
30 ngx_url_t u; | |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
31 ngx_uint_t i, j, n, w; |
884 | 32 ngx_http_upstream_server_t *server; |
1378 | 33 ngx_http_upstream_rr_peers_t *peers, *backup; |
884 | 34 |
35 us->peer.init = ngx_http_upstream_init_round_robin_peer; | |
36 | |
37 if (us->servers) { | |
38 server = us->servers->elts; | |
39 | |
1378 | 40 n = 0; |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
41 w = 0; |
1378 | 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; |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
49 w += server[i].naddrs * server[i].weight; |
884 | 50 } |
51 | |
4569
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
52 if (n == 0) { |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
53 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
54 "no servers in upstream \"%V\" in %s:%ui", |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
55 &us->host, us->file_name, us->line); |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
56 return NGX_ERROR; |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
57 } |
1db899642518
Upstream: reject upstreams without normal servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
58 |
884 | 59 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) |
60 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
61 if (peers == NULL) { | |
62 return NGX_ERROR; | |
63 } | |
64 | |
1378 | 65 peers->single = (n == 1); |
884 | 66 peers->number = n; |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
67 peers->weighted = (w != n); |
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
68 peers->total_weight = w; |
884 | 69 peers->name = &us->host; |
70 | |
71 n = 0; | |
72 | |
73 for (i = 0; i < us->servers->nelts; i++) { | |
5429
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
74 if (server[i].backup) { |
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
75 continue; |
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
76 } |
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
77 |
884 | 78 for (j = 0; j < server[i].naddrs; j++) { |
79 peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
80 peers->peer[n].socklen = server[i].addrs[j].socklen; | |
81 peers->peer[n].name = server[i].addrs[j].name; | |
5454
359f49a84f87
Improved code readablity in ngx_http_upstream_init_round_robin().
Vladimir Homutov <vl@nginx.com>
parents:
5429
diff
changeset
|
82 peers->peer[n].weight = server[i].weight; |
359f49a84f87
Improved code readablity in ngx_http_upstream_init_round_robin().
Vladimir Homutov <vl@nginx.com>
parents:
5429
diff
changeset
|
83 peers->peer[n].effective_weight = server[i].weight; |
359f49a84f87
Improved code readablity in ngx_http_upstream_init_round_robin().
Vladimir Homutov <vl@nginx.com>
parents:
5429
diff
changeset
|
84 peers->peer[n].current_weight = 0; |
884 | 85 peers->peer[n].max_fails = server[i].max_fails; |
86 peers->peer[n].fail_timeout = server[i].fail_timeout; | |
87 peers->peer[n].down = server[i].down; | |
88 n++; | |
89 } | |
90 } | |
91 | |
92 us->peer.data = peers; | |
93 | |
1378 | 94 /* backup servers */ |
95 | |
96 n = 0; | |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
97 w = 0; |
1378 | 98 |
99 for (i = 0; i < us->servers->nelts; i++) { | |
100 if (!server[i].backup) { | |
101 continue; | |
102 } | |
103 | |
104 n += server[i].naddrs; | |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
105 w += server[i].naddrs * server[i].weight; |
1378 | 106 } |
107 | |
108 if (n == 0) { | |
109 return NGX_OK; | |
110 } | |
111 | |
112 backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
113 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
114 if (backup == NULL) { | |
115 return NGX_ERROR; | |
116 } | |
117 | |
118 peers->single = 0; | |
119 backup->single = 0; | |
120 backup->number = n; | |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
121 backup->weighted = (w != n); |
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
122 backup->total_weight = w; |
1378 | 123 backup->name = &us->host; |
124 | |
125 n = 0; | |
126 | |
127 for (i = 0; i < us->servers->nelts; i++) { | |
5429
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
128 if (!server[i].backup) { |
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
129 continue; |
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
130 } |
e6a1623f87bc
Upstream: optimize loops in ngx_http_upstream_init_round_robin().
Xiaochen Wang <wangxiaochen0@gmail.com>
parents:
5220
diff
changeset
|
131 |
1378 | 132 for (j = 0; j < server[i].naddrs; j++) { |
133 backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; | |
134 backup->peer[n].socklen = server[i].addrs[j].socklen; | |
135 backup->peer[n].name = server[i].addrs[j].name; | |
136 backup->peer[n].weight = server[i].weight; | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
137 backup->peer[n].effective_weight = server[i].weight; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
138 backup->peer[n].current_weight = 0; |
1378 | 139 backup->peer[n].max_fails = server[i].max_fails; |
140 backup->peer[n].fail_timeout = server[i].fail_timeout; | |
141 backup->peer[n].down = server[i].down; | |
142 n++; | |
143 } | |
144 } | |
145 | |
146 peers->next = backup; | |
147 | |
884 | 148 return NGX_OK; |
149 } | |
150 | |
151 | |
152 /* an upstream implicitly defined by proxy_pass, etc. */ | |
153 | |
5005
c9059bd5445b
Fixed "proxy_pass" with IP address and no port (ticket #276).
Ruslan Ermilov <ru@nginx.com>
parents:
4991
diff
changeset
|
154 if (us->port == 0) { |
906 | 155 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
156 "no port in upstream \"%V\" in %s:%ui", | |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1465
diff
changeset
|
157 &us->host, us->file_name, us->line); |
906 | 158 return NGX_ERROR; |
159 } | |
160 | |
884 | 161 ngx_memzero(&u, sizeof(ngx_url_t)); |
162 | |
163 u.host = us->host; | |
5005
c9059bd5445b
Fixed "proxy_pass" with IP address and no port (ticket #276).
Ruslan Ermilov <ru@nginx.com>
parents:
4991
diff
changeset
|
164 u.port = us->port; |
884 | 165 |
1559
fe11e2a3946d
use pool instead of ngx_conf_t
Igor Sysoev <igor@sysoev.ru>
parents:
1556
diff
changeset
|
166 if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { |
884 | 167 if (u.err) { |
168 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
896
f247db60fc85
fix fastcgi and memcached upstreams
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
169 "%s in upstream \"%V\" in %s:%ui", |
1489
56f1ea5baabb
u_char* is enough to keep file name
Igor Sysoev <igor@sysoev.ru>
parents:
1465
diff
changeset
|
170 u.err, &us->host, us->file_name, us->line); |
884 | 171 } |
172 | |
173 return NGX_ERROR; | |
174 } | |
175 | |
176 n = u.naddrs; | |
177 | |
178 peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) | |
179 + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); | |
180 if (peers == NULL) { | |
181 return NGX_ERROR; | |
182 } | |
183 | |
1378 | 184 peers->single = (n == 1); |
884 | 185 peers->number = n; |
4655
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
186 peers->weighted = 0; |
382c523d253a
Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4622
diff
changeset
|
187 peers->total_weight = n; |
884 | 188 peers->name = &us->host; |
189 | |
190 for (i = 0; i < u.naddrs; i++) { | |
1564 | 191 peers->peer[i].sockaddr = u.addrs[i].sockaddr; |
192 peers->peer[i].socklen = u.addrs[i].socklen; | |
193 peers->peer[i].name = u.addrs[i].name; | |
194 peers->peer[i].weight = 1; | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
195 peers->peer[i].effective_weight = 1; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
196 peers->peer[i].current_weight = 0; |
1564 | 197 peers->peer[i].max_fails = 1; |
198 peers->peer[i].fail_timeout = 10; | |
884 | 199 } |
200 | |
201 us->peer.data = peers; | |
202 | |
1378 | 203 /* implicitly defined upstream has no backup servers */ |
204 | |
884 | 205 return NGX_OK; |
206 } | |
207 | |
208 | |
209 ngx_int_t | |
210 ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r, | |
211 ngx_http_upstream_srv_conf_t *us) | |
212 { | |
213 ngx_uint_t n; | |
214 ngx_http_upstream_rr_peer_data_t *rrp; | |
215 | |
216 rrp = r->upstream->peer.data; | |
217 | |
218 if (rrp == NULL) { | |
219 rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t)); | |
220 if (rrp == NULL) { | |
221 return NGX_ERROR; | |
222 } | |
223 | |
224 r->upstream->peer.data = rrp; | |
225 } | |
226 | |
227 rrp->peers = us->peer.data; | |
228 rrp->current = 0; | |
229 | |
4011
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
230 n = rrp->peers->number; |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
231 |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
232 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
|
233 n = rrp->peers->next->number; |
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
234 } |
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 if (n <= 8 * sizeof(uintptr_t)) { |
884 | 237 rrp->tried = &rrp->data; |
238 rrp->data = 0; | |
239 | |
240 } else { | |
4011
9d4cbb09ae8b
Upstream: properly allocate memory for tried flags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4010
diff
changeset
|
241 n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t)); |
884 | 242 |
243 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
244 if (rrp->tried == NULL) { | |
245 return NGX_ERROR; | |
246 } | |
247 } | |
248 | |
249 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
250 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
251 r->upstream->peer.tries = rrp->peers->number; | |
252 #if (NGX_HTTP_SSL) | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
253 r->upstream->peer.set_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
254 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
|
255 r->upstream->peer.save_session = |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
256 ngx_http_upstream_save_round_robin_peer_session; |
884 | 257 #endif |
258 | |
259 return NGX_OK; | |
260 } | |
261 | |
262 | |
263 ngx_int_t | |
1658 | 264 ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, |
265 ngx_http_upstream_resolved_t *ur) | |
266 { | |
267 u_char *p; | |
268 size_t len; | |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
269 socklen_t socklen; |
1658 | 270 ngx_uint_t i, n; |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
271 struct sockaddr *sockaddr; |
1658 | 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; |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
301 peers->peer[0].effective_weight = 1; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
302 peers->peer[0].current_weight = 0; |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
303 peers->peer[0].max_fails = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
304 peers->peer[0].fail_timeout = 10; |
1658 | 305 |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
306 } else { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
307 |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
308 for (i = 0; i < ur->naddrs; i++) { |
1658 | 309 |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
310 socklen = ur->addrs[i].socklen; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
311 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
312 sockaddr = ngx_palloc(r->pool, socklen); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
313 if (sockaddr == NULL) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
314 return NGX_ERROR; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
315 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
316 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
317 ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
318 |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
319 switch (sockaddr->sa_family) { |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
320 #if (NGX_HAVE_INET6) |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
321 case AF_INET6: |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
322 ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
323 break; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
324 #endif |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
325 default: /* AF_INET */ |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
326 ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port); |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
327 } |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
328 |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
329 p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN); |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
330 if (p == NULL) { |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
331 return NGX_ERROR; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
332 } |
1658 | 333 |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
334 len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1); |
1658 | 335 |
5475
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
336 peers->peer[i].sockaddr = sockaddr; |
07dd5bd222ac
Changed resolver API to use ngx_addr_t.
Ruslan Ermilov <ru@nginx.com>
parents:
5454
diff
changeset
|
337 peers->peer[i].socklen = socklen; |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
338 peers->peer[i].name.len = len; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
339 peers->peer[i].name.data = p; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
340 peers->peer[i].weight = 1; |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
341 peers->peer[i].effective_weight = 1; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
342 peers->peer[i].current_weight = 0; |
2422
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
343 peers->peer[i].max_fails = 1; |
7af1e5fe102c
variable support for unix sockets in fastcgi_pass and proxy_pass
Igor Sysoev <igor@sysoev.ru>
parents:
2204
diff
changeset
|
344 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
|
345 } |
1658 | 346 } |
347 | |
348 rrp->peers = peers; | |
349 rrp->current = 0; | |
350 | |
351 if (rrp->peers->number <= 8 * sizeof(uintptr_t)) { | |
352 rrp->tried = &rrp->data; | |
353 rrp->data = 0; | |
354 | |
355 } else { | |
356 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) | |
357 / (8 * sizeof(uintptr_t)); | |
358 | |
359 rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t)); | |
360 if (rrp->tried == NULL) { | |
361 return NGX_ERROR; | |
362 } | |
363 } | |
364 | |
365 r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer; | |
366 r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer; | |
367 r->upstream->peer.tries = rrp->peers->number; | |
368 #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
|
369 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
|
370 r->upstream->peer.save_session = ngx_http_upstream_empty_save_session; |
1658 | 371 #endif |
372 | |
373 return NGX_OK; | |
374 } | |
375 | |
376 | |
377 ngx_int_t | |
884 | 378 ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data) |
379 { | |
380 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
381 | |
1378 | 382 ngx_int_t rc; |
383 ngx_uint_t i, n; | |
384 ngx_http_upstream_rr_peer_t *peer; | |
385 ngx_http_upstream_rr_peers_t *peers; | |
884 | 386 |
387 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
388 "get rr peer, try: %ui", pc->tries); | |
389 | |
390 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
391 | |
392 pc->cached = 0; | |
393 pc->connection = NULL; | |
394 | |
1378 | 395 if (rrp->peers->single) { |
884 | 396 peer = &rrp->peers->peer[0]; |
397 | |
4914
dcb853acae97
Upstream: honor the "down" flag for a single server.
Ruslan Ermilov <ru@nginx.com>
parents:
4655
diff
changeset
|
398 if (peer->down) { |
dcb853acae97
Upstream: honor the "down" flag for a single server.
Ruslan Ermilov <ru@nginx.com>
parents:
4655
diff
changeset
|
399 goto failed; |
dcb853acae97
Upstream: honor the "down" flag for a single server.
Ruslan Ermilov <ru@nginx.com>
parents:
4655
diff
changeset
|
400 } |
dcb853acae97
Upstream: honor the "down" flag for a single server.
Ruslan Ermilov <ru@nginx.com>
parents:
4655
diff
changeset
|
401 |
884 | 402 } else { |
403 | |
404 /* there are several peers */ | |
405 | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
406 peer = ngx_http_upstream_get_peer(rrp); |
884 | 407 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
408 if (peer == NULL) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
409 goto failed; |
884 | 410 } |
411 | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
412 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
413 "get rr peer, current: %ui %i", |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
414 rrp->current, peer->current_weight); |
884 | 415 } |
416 | |
417 pc->sockaddr = peer->sockaddr; | |
418 pc->socklen = peer->socklen; | |
419 pc->name = &peer->name; | |
420 | |
421 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
422 | |
1378 | 423 if (pc->tries == 1 && rrp->peers->next) { |
424 pc->tries += rrp->peers->next->number; | |
425 } | |
426 | |
884 | 427 return NGX_OK; |
428 | |
429 failed: | |
430 | |
1378 | 431 peers = rrp->peers; |
432 | |
433 if (peers->next) { | |
434 | |
435 /* ngx_unlock_mutex(peers->mutex); */ | |
436 | |
437 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers"); | |
438 | |
439 rrp->peers = peers->next; | |
440 pc->tries = rrp->peers->number; | |
441 | |
4991
a384c60d55f3
Upstream: fixed state resetting when switching to backup servers.
Valentin Bartenev <vbart@nginx.com>
parents:
4914
diff
changeset
|
442 n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1)) |
a384c60d55f3
Upstream: fixed state resetting when switching to backup servers.
Valentin Bartenev <vbart@nginx.com>
parents:
4914
diff
changeset
|
443 / (8 * sizeof(uintptr_t)); |
a384c60d55f3
Upstream: fixed state resetting when switching to backup servers.
Valentin Bartenev <vbart@nginx.com>
parents:
4914
diff
changeset
|
444 |
1389 | 445 for (i = 0; i < n; i++) { |
1378 | 446 rrp->tried[i] = 0; |
447 } | |
448 | |
449 rc = ngx_http_upstream_get_round_robin_peer(pc, rrp); | |
450 | |
451 if (rc != NGX_BUSY) { | |
452 return rc; | |
453 } | |
454 | |
455 /* ngx_lock_mutex(peers->mutex); */ | |
456 } | |
457 | |
884 | 458 /* all peers failed, mark them as live for quick recovery */ |
459 | |
1378 | 460 for (i = 0; i < peers->number; i++) { |
461 peers->peer[i].fails = 0; | |
884 | 462 } |
463 | |
1378 | 464 /* ngx_unlock_mutex(peers->mutex); */ |
884 | 465 |
1378 | 466 pc->name = peers->name; |
884 | 467 |
468 return NGX_BUSY; | |
469 } | |
470 | |
471 | |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
472 static ngx_http_upstream_rr_peer_t * |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
473 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp) |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
474 { |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
475 time_t now; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
476 uintptr_t m; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
477 ngx_int_t total; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
478 ngx_uint_t i, n; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
479 ngx_http_upstream_rr_peer_t *peer, *best; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
480 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
481 now = ngx_time(); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
482 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
483 best = NULL; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
484 total = 0; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
485 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
486 for (i = 0; i < rrp->peers->number; i++) { |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
487 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
488 n = i / (8 * sizeof(uintptr_t)); |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
489 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
490 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
491 if (rrp->tried[n] & m) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
492 continue; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
493 } |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
494 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
495 peer = &rrp->peers->peer[i]; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
496 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
497 if (peer->down) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
498 continue; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
499 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
500 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
501 if (peer->max_fails |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
502 && peer->fails >= peer->max_fails |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
503 && now - peer->checked <= peer->fail_timeout) |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
504 { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
505 continue; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
506 } |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
507 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
508 peer->current_weight += peer->effective_weight; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
509 total += peer->effective_weight; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
510 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
511 if (peer->effective_weight < peer->weight) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
512 peer->effective_weight++; |
4010
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
513 } |
74a93d3fdd85
Fixing cpu hog with all upstream servers marked "down".
Maxim Dounin <mdounin@mdounin.ru>
parents:
3964
diff
changeset
|
514 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
515 if (best == NULL || peer->current_weight > best->current_weight) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
516 best = peer; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
517 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
518 } |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
519 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
520 if (best == NULL) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
521 return NULL; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
522 } |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
523 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
524 i = best - &rrp->peers->peer[0]; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
525 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
526 rrp->current = i; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
527 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
528 n = i / (8 * sizeof(uintptr_t)); |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
529 m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t)); |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
530 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
531 rrp->tried[n] |= m; |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
532 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
533 best->current_weight -= total; |
5220
1d68b502088c
Upstream: fixed fail_timeout and max_fails > 1.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5136
diff
changeset
|
534 |
1d68b502088c
Upstream: fixed fail_timeout and max_fails > 1.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5136
diff
changeset
|
535 if (now - best->checked > best->fail_timeout) { |
1d68b502088c
Upstream: fixed fail_timeout and max_fails > 1.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5136
diff
changeset
|
536 best->checked = now; |
1d68b502088c
Upstream: fixed fail_timeout and max_fails > 1.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5136
diff
changeset
|
537 } |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
538 |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
539 return best; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
540 } |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
541 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
542 |
884 | 543 void |
544 ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, | |
545 ngx_uint_t state) | |
546 { | |
547 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
548 | |
549 time_t now; | |
550 ngx_http_upstream_rr_peer_t *peer; | |
551 | |
552 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
553 "free rr peer %ui %ui", pc->tries, state); | |
554 | |
555 /* TODO: NGX_PEER_KEEPALIVE */ | |
556 | |
1378 | 557 if (rrp->peers->single) { |
884 | 558 pc->tries = 0; |
559 return; | |
560 } | |
561 | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
562 peer = &rrp->peers->peer[rrp->current]; |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
563 |
884 | 564 if (state & NGX_PEER_FAILED) { |
565 now = ngx_time(); | |
566 | |
567 /* ngx_lock_mutex(rrp->peers->mutex); */ | |
568 | |
569 peer->fails++; | |
570 peer->accessed = now; | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
571 peer->checked = now; |
884 | 572 |
2204
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
573 if (peer->max_fails) { |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
574 peer->effective_weight -= peer->weight / peer->max_fails; |
2204
70a2bcc7e307
fix divide by zero if max_fails=0
Igor Sysoev <igor@sysoev.ru>
parents:
2197
diff
changeset
|
575 } |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
576 |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
577 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
578 "free rr peer failed: %ui %i", |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
579 rrp->current, peer->effective_weight); |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
580 |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
581 if (peer->effective_weight < 0) { |
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4569
diff
changeset
|
582 peer->effective_weight = 0; |
884 | 583 } |
584 | |
585 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
586 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
587 } else { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
588 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
589 /* mark peer live if check passed */ |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
590 |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
591 if (peer->accessed < peer->checked) { |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
592 peer->fails = 0; |
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4011
diff
changeset
|
593 } |
884 | 594 } |
595 | |
596 if (pc->tries) { | |
597 pc->tries--; | |
598 } | |
599 | |
600 /* ngx_unlock_mutex(rrp->peers->mutex); */ | |
601 } | |
602 | |
603 | |
604 #if (NGX_HTTP_SSL) | |
605 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
606 ngx_int_t |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
607 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
|
608 void *data) |
884 | 609 { |
610 ngx_http_upstream_rr_peer_data_t *rrp = data; | |
611 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
612 ngx_int_t rc; |
884 | 613 ngx_ssl_session_t *ssl_session; |
614 ngx_http_upstream_rr_peer_t *peer; | |
615 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
616 peer = &rrp->peers->peer[rrp->current]; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
617 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
618 /* TODO: threads only mutex */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
619 /* ngx_lock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
620 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
621 ssl_session = peer->ssl_session; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
622 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
623 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
|
624 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
625 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 626 "set session: %p:%d", |
627 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
|
628 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
629 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
630 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
631 return rc; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
632 } |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
633 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
634 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
635 void |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
636 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
|
637 void *data) |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
638 { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
639 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
|
640 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
641 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
|
642 ngx_http_upstream_rr_peer_t *peer; |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
643 |
884 | 644 ssl_session = ngx_ssl_get_session(pc->connection); |
645 | |
646 if (ssl_session == NULL) { | |
647 return; | |
648 } | |
649 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
650 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 651 "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
|
652 |
884 | 653 peer = &rrp->peers->peer[rrp->current]; |
654 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
655 /* TODO: threads only mutex */ |
884 | 656 /* ngx_lock_mutex(rrp->peers->mutex); */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
657 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
658 old_ssl_session = peer->ssl_session; |
884 | 659 peer->ssl_session = ssl_session; |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
660 |
884 | 661 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
662 | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
663 if (old_ssl_session) { |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
664 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
665 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, |
1443 | 666 "old session: %p:%d", |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
667 old_ssl_session, old_ssl_session->references); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
668 |
884 | 669 /* TODO: may block */ |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
670 |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
1206
diff
changeset
|
671 ngx_ssl_free_session(old_ssl_session); |
884 | 672 } |
673 } | |
674 | |
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
|
675 |
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
|
676 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
|
677 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
|
678 { |
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
|
679 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
|
680 } |
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
|
681 |
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
|
682 |
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
|
683 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
|
684 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
|
685 { |
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
|
686 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
|
687 } |
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
|
688 |
884 | 689 #endif |