Mercurial > hg > nginx-quic
annotate src/http/ngx_http_upstream_round_robin.h @ 4621:c90801720a0c
Upstream: smooth weighted round-robin balancing.
For edge case weights like { 5, 1, 1 } we now produce { a, a, b, a, c, a, a }
sequence instead of { c, b, a, a, a, a, a } produced previously.
Algorithm is as follows: on each peer selection we increase current_weight
of each eligible peer by its weight, select peer with greatest current_weight
and reduce its current_weight by total number of weight points distributed
among peers.
In case of { 5, 1, 1 } weights this gives the following sequence of
current_weight's:
a b c
0 0 0 (initial state)
5 1 1 (a selected)
-2 1 1
3 2 2 (a selected)
-4 2 2
1 3 3 (b selected)
1 -4 3
6 -3 4 (a selected)
-1 -3 4
4 -2 5 (c selected)
4 -2 -2
9 -1 -1 (a selected)
2 -1 -1
7 0 0 (a selected)
0 0 0
To preserve weight reduction in case of failures the effective_weight
variable was introduced, which usually matches peer's weight, but is
reduced temporarily on peer failures.
This change also fixes loop with backup servers and proxy_next_upstream
http_404 (ticket #47), and skipping alive upstreams in some cases if there
are multiple dead ones (ticket #64).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 14 May 2012 09:57:20 +0000 |
parents | d620f497c50f |
children | 382c523d253a |
rev | line source |
---|---|
884 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
884 | 5 */ |
6 | |
7 | |
8 #ifndef _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ | |
9 #define _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ | |
10 | |
11 | |
12 #include <ngx_config.h> | |
13 #include <ngx_core.h> | |
14 #include <ngx_http.h> | |
15 | |
16 | |
17 typedef struct { | |
18 struct sockaddr *sockaddr; | |
19 socklen_t socklen; | |
20 ngx_str_t name; | |
21 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
22 ngx_int_t current_weight; |
4621
c90801720a0c
Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
23 ngx_int_t effective_weight; |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
24 ngx_int_t weight; |
884 | 25 |
26 ngx_uint_t fails; | |
27 time_t accessed; | |
4207
4fc91bae6f83
Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
3264
diff
changeset
|
28 time_t checked; |
884 | 29 |
30 ngx_uint_t max_fails; | |
31 time_t fail_timeout; | |
32 | |
33 ngx_uint_t down; /* unsigned down:1; */ | |
34 | |
1344
8f5b5641966c
fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents:
1284
diff
changeset
|
35 #if (NGX_HTTP_SSL) |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
954
diff
changeset
|
36 ngx_ssl_session_t *ssl_session; /* local to a process */ |
884 | 37 #endif |
38 } ngx_http_upstream_rr_peer_t; | |
39 | |
40 | |
1378 | 41 typedef struct ngx_http_upstream_rr_peers_s ngx_http_upstream_rr_peers_t; |
42 | |
43 struct ngx_http_upstream_rr_peers_s { | |
44 ngx_uint_t single; /* unsigned single:1; */ | |
884 | 45 ngx_uint_t number; |
46 ngx_uint_t last_cached; | |
47 | |
48 /* ngx_mutex_t *mutex; */ | |
49 ngx_connection_t **cached; | |
50 | |
51 ngx_str_t *name; | |
52 | |
1378 | 53 ngx_http_upstream_rr_peers_t *next; |
54 | |
884 | 55 ngx_http_upstream_rr_peer_t peer[1]; |
1378 | 56 }; |
884 | 57 |
58 | |
59 typedef struct { | |
60 ngx_http_upstream_rr_peers_t *peers; | |
61 ngx_uint_t current; | |
954
f16424aa5d89
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
884
diff
changeset
|
62 uintptr_t *tried; |
884 | 63 uintptr_t data; |
64 } ngx_http_upstream_rr_peer_data_t; | |
65 | |
66 | |
67 ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf, | |
68 ngx_http_upstream_srv_conf_t *us); | |
69 ngx_int_t ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r, | |
70 ngx_http_upstream_srv_conf_t *us); | |
1658 | 71 ngx_int_t ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r, |
72 ngx_http_upstream_resolved_t *ur); | |
884 | 73 ngx_int_t ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, |
74 void *data); | |
75 void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, | |
76 void *data, ngx_uint_t state); | |
77 | |
78 #if (NGX_HTTP_SSL) | |
1284
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
954
diff
changeset
|
79 ngx_int_t |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
954
diff
changeset
|
80 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:
954
diff
changeset
|
81 void *data); |
be2b895d31e0
fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents:
954
diff
changeset
|
82 void ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc, |
884 | 83 void *data); |
84 #endif | |
85 | |
86 | |
87 #endif /* _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */ |