Mercurial > hg > nginx-vendor-current
comparison src/http/ngx_http_upstream_round_robin.c @ 324:f7cd062ee035 NGINX_0_6_6
nginx 0.6.6
*) Feature: the --sysconfdir=PATH option in configure.
*) Feature: named locations.
*) Feature: the $args variable can be set with the "set" directive.
*) Feature: the $is_args variable.
*) Bugfix: fair big weight upstream balancer.
*) Bugfix: if a client has closed connection to mail proxy then nginx
might not close connection to backend.
*) Bugfix: if the same host without specified port was used as backend
for HTTP and HTTPS, then nginx used only one port - 80 or 443.
*) Bugfix: fix building on Solaris/amd64 by Sun Studio 11 and early
versions; bug appeared in 0.6.4.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 30 Jul 2007 00:00:00 +0400 |
parents | fc223117327f |
children | 9fc4ab6673f9 |
comparison
equal
deleted
inserted
replaced
323:7e977a664d91 | 324:f7cd062ee035 |
---|---|
5 | 5 |
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | |
11 | |
12 static ngx_uint_t | |
13 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers); | |
10 | 14 |
11 | 15 |
12 ngx_int_t | 16 ngx_int_t |
13 ngx_http_upstream_init_round_robin(ngx_conf_t *cf, | 17 ngx_http_upstream_init_round_robin(ngx_conf_t *cf, |
14 ngx_http_upstream_srv_conf_t *us) | 18 ngx_http_upstream_srv_conf_t *us) |
213 if (pc->tries == rrp->peers->number) { | 217 if (pc->tries == rrp->peers->number) { |
214 | 218 |
215 /* it's a first try - get a current peer */ | 219 /* it's a first try - get a current peer */ |
216 | 220 |
217 for ( ;; ) { | 221 for ( ;; ) { |
218 rrp->current = rrp->peers->current; | 222 rrp->current = ngx_http_upstream_get_peer(rrp->peers); |
223 | |
224 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
225 "get rr peer, current: %ui %i", | |
226 rrp->current, | |
227 rrp->peers->peer[rrp->current].current_weight); | |
219 | 228 |
220 n = rrp->current / (8 * sizeof(uintptr_t)); | 229 n = rrp->current / (8 * sizeof(uintptr_t)); |
221 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); | 230 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); |
222 | 231 |
223 if (!(rrp->tried[n] & m)) { | 232 if (!(rrp->tried[n] & m)) { |
234 if (now - peer->accessed > peer->fail_timeout) { | 243 if (now - peer->accessed > peer->fail_timeout) { |
235 peer->fails = 0; | 244 peer->fails = 0; |
236 break; | 245 break; |
237 } | 246 } |
238 | 247 |
248 peer->current_weight = 0; | |
249 | |
239 } else { | 250 } else { |
240 rrp->tried[n] |= m; | 251 rrp->tried[n] |= m; |
241 } | 252 } |
242 | 253 |
243 pc->tries--; | 254 pc->tries--; |
244 } | 255 } |
245 | 256 |
246 rrp->peers->current++; | |
247 | |
248 if (rrp->peers->current >= rrp->peers->number) { | |
249 rrp->peers->current = 0; | |
250 } | |
251 | |
252 if (pc->tries) { | 257 if (pc->tries) { |
253 continue; | 258 continue; |
254 } | 259 } |
255 | 260 |
256 goto failed; | 261 goto failed; |
257 } | 262 } |
258 | 263 |
259 peer->current_weight--; | 264 peer->current_weight--; |
260 | |
261 if (peer->current_weight == 0) { | |
262 peer->current_weight = peer->weight; | |
263 | |
264 rrp->peers->current++; | |
265 | |
266 if (rrp->peers->current >= rrp->peers->number) { | |
267 rrp->peers->current = 0; | |
268 } | |
269 } | |
270 | 265 |
271 } else { | 266 } else { |
272 for ( ;; ) { | 267 for ( ;; ) { |
273 n = rrp->current / (8 * sizeof(uintptr_t)); | 268 n = rrp->current / (8 * sizeof(uintptr_t)); |
274 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); | 269 m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t)); |
288 if (now - peer->accessed > peer->fail_timeout) { | 283 if (now - peer->accessed > peer->fail_timeout) { |
289 peer->fails = 0; | 284 peer->fails = 0; |
290 break; | 285 break; |
291 } | 286 } |
292 | 287 |
288 peer->current_weight = 0; | |
289 | |
293 } else { | 290 } else { |
294 rrp->tried[n] |= m; | 291 rrp->tried[n] |= m; |
295 } | 292 } |
296 | 293 |
297 pc->tries--; | 294 pc->tries--; |
309 | 306 |
310 goto failed; | 307 goto failed; |
311 } | 308 } |
312 | 309 |
313 peer->current_weight--; | 310 peer->current_weight--; |
314 | |
315 if (peer->current_weight == 0) { | |
316 peer->current_weight = peer->weight; | |
317 | |
318 if (rrp->current == rrp->peers->current) { | |
319 rrp->peers->current++; | |
320 | |
321 if (rrp->peers->current >= rrp->peers->number) { | |
322 rrp->peers->current = 0; | |
323 } | |
324 } | |
325 } | |
326 } | 311 } |
327 | 312 |
328 rrp->tried[n] |= m; | 313 rrp->tried[n] |= m; |
329 } | 314 } |
330 | 315 |
350 | 335 |
351 return NGX_BUSY; | 336 return NGX_BUSY; |
352 } | 337 } |
353 | 338 |
354 | 339 |
340 static ngx_uint_t | |
341 ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers) | |
342 { | |
343 ngx_uint_t i, n; | |
344 ngx_http_upstream_rr_peer_t *peer; | |
345 | |
346 peer = &peers->peer[0]; | |
347 | |
348 for ( ;; ) { | |
349 | |
350 for (i = 0; i < peers->number; i++) { | |
351 | |
352 if (peer[i].current_weight <= 0) { | |
353 continue; | |
354 } | |
355 | |
356 n = i; | |
357 | |
358 while (i < peers->number - 1) { | |
359 | |
360 i++; | |
361 | |
362 if (peer[i].current_weight <= 0) { | |
363 continue; | |
364 } | |
365 | |
366 if (peer[n].current_weight * 1000 / peer[i].current_weight | |
367 >= peer[n].weight * 1000 / peer[i].weight) | |
368 { | |
369 return n; | |
370 } | |
371 | |
372 n = i; | |
373 } | |
374 | |
375 if (peer[i].current_weight > 0) { | |
376 n = i; | |
377 } | |
378 | |
379 return n; | |
380 } | |
381 | |
382 for (i = 0; i < peers->number; i++) { | |
383 if (peer[i].fails == 0) { | |
384 peer[i].current_weight += peer[i].weight; | |
385 | |
386 } else { | |
387 /* 1 allows to go to quick recovery when all peers failed */ | |
388 peer[i].current_weight = 1; | |
389 } | |
390 } | |
391 } | |
392 } | |
393 | |
394 | |
355 void | 395 void |
356 ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, | 396 ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data, |
357 ngx_uint_t state) | 397 ngx_uint_t state) |
358 { | 398 { |
359 ngx_http_upstream_rr_peer_data_t *rrp = data; | 399 ngx_http_upstream_rr_peer_data_t *rrp = data; |
383 /* ngx_lock_mutex(rrp->peers->mutex); */ | 423 /* ngx_lock_mutex(rrp->peers->mutex); */ |
384 | 424 |
385 peer->fails++; | 425 peer->fails++; |
386 peer->accessed = now; | 426 peer->accessed = now; |
387 | 427 |
388 if (peer->current_weight > 1) { | 428 peer->current_weight -= peer->weight / peer->max_fails; |
389 peer->current_weight /= 2; | 429 |
430 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, | |
431 "free rr peer failed: %ui %i", | |
432 rrp->current, peer->current_weight); | |
433 | |
434 if (peer->current_weight < 0) { | |
435 peer->current_weight = 0; | |
390 } | 436 } |
391 | 437 |
392 /* ngx_unlock_mutex(rrp->peers->mutex); */ | 438 /* ngx_unlock_mutex(rrp->peers->mutex); */ |
393 } | 439 } |
394 | 440 |