* added the 'source' load-balancing algorithm which uses the source IP(v4|v6)
This commit is contained in:
parent
b8d29e4361
commit
1a3442daee
90
haproxy.c
90
haproxy.c
@ -332,7 +332,6 @@ int strlcpy2(char *dst, const char *src, int size) {
|
||||
#define PR_O_COOK_PFX 0x00000020 /* rewrite all cookies by prefixing the right serverid */
|
||||
#define PR_O_COOK_ANY (PR_O_COOK_RW | PR_O_COOK_IND | PR_O_COOK_INS | PR_O_COOK_PFX)
|
||||
#define PR_O_BALANCE_RR 0x00000040 /* balance in round-robin mode */
|
||||
#define PR_O_BALANCE (PR_O_BALANCE_RR)
|
||||
#define PR_O_KEEPALIVE 0x00000080 /* follow keep-alive sessions */
|
||||
#define PR_O_FWDFOR 0x00000100 /* insert x-forwarded-for with client address */
|
||||
#define PR_O_BIND_SRC 0x00000200 /* bind to a specific source address when connect()ing */
|
||||
@ -348,6 +347,8 @@ int strlcpy2(char *dst, const char *src, int size) {
|
||||
#define PR_O_TCP_SRV_KA 0x00080000 /* enable TCP keep-alive on server-side sessions */
|
||||
#define PR_O_USE_ALL_BK 0x00100000 /* load-balance between backup servers */
|
||||
#define PR_O_FORCE_CLO 0x00200000 /* enforce the connection close immediately after server response */
|
||||
#define PR_O_BALANCE_SH 0x00400000 /* balance on source IP hash */
|
||||
#define PR_O_BALANCE (PR_O_BALANCE_RR | PR_O_BALANCE_SH)
|
||||
|
||||
/* various session flags */
|
||||
#define SN_DIRECT 0x00000001 /* connection made on the server matching the client cookie */
|
||||
@ -1861,6 +1862,69 @@ static inline struct server *get_server_rr(struct proxy *px) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function tries to find a running server for the proxy <px> following
|
||||
* the source hash method. Depending on the number of active/backup servers,
|
||||
* it will either look for active servers, or for backup servers.
|
||||
* If any server is found, it will be returned. If no valid server is found,
|
||||
* NULL is returned.
|
||||
*/
|
||||
static inline struct server *get_server_sh(struct proxy *px, char *addr, int len) {
|
||||
struct server *srv;
|
||||
|
||||
if (px->srv_act) {
|
||||
unsigned int h, l;
|
||||
|
||||
l = h = 0;
|
||||
if (px->srv_act > 1) {
|
||||
while ((l + sizeof (int)) <= len) {
|
||||
h ^= ntohl(*(unsigned int *)(&addr[l]));
|
||||
l += sizeof (int);
|
||||
}
|
||||
h %= px->srv_act;
|
||||
}
|
||||
|
||||
for (srv = px->srv; srv; srv = srv->next) {
|
||||
if ((srv->state & (SRV_RUNNING | SRV_BACKUP)) == SRV_RUNNING) {
|
||||
if (!h)
|
||||
return srv;
|
||||
h--;
|
||||
}
|
||||
}
|
||||
/* note that theorically we should not get there */
|
||||
}
|
||||
|
||||
if (px->srv_bck) {
|
||||
unsigned int h, l;
|
||||
|
||||
/* By default, we look for the first backup server if all others are
|
||||
* DOWN. But in some cases, it may be desirable to load-balance across
|
||||
* all backup servers.
|
||||
*/
|
||||
l = h = 0;
|
||||
if (px->srv_bck > 1 && px->options & PR_O_USE_ALL_BK) {
|
||||
while ((l + sizeof (int)) <= len) {
|
||||
h ^= ntohl(*(unsigned int *)(&addr[l]));
|
||||
l += sizeof (int);
|
||||
}
|
||||
h %= px->srv_bck;
|
||||
}
|
||||
|
||||
for (srv = px->srv; srv; srv = srv->next) {
|
||||
if (srv->state & SRV_RUNNING) {
|
||||
if (!h)
|
||||
return srv;
|
||||
h--;
|
||||
}
|
||||
}
|
||||
/* note that theorically we should not get there */
|
||||
}
|
||||
|
||||
/* if we get there, it means there are no available servers at all */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function initiates a connection to the current server (s->srv) if (s->direct)
|
||||
* is set, or to the dispatch server if (s->direct) is 0.
|
||||
@ -1884,6 +1948,7 @@ int connect_server(struct session *s) {
|
||||
s->srv_addr = s->srv->addr;
|
||||
}
|
||||
else if (s->proxy->options & PR_O_BALANCE) {
|
||||
/* Ensure that srv will not be NULL */
|
||||
if (!s->proxy->srv_act && !s->proxy->srv_bck)
|
||||
return SN_ERR_SRVTO;
|
||||
|
||||
@ -1891,7 +1956,23 @@ int connect_server(struct session *s) {
|
||||
struct server *srv;
|
||||
|
||||
srv = get_server_rr(s->proxy);
|
||||
/* srv cannot be NULL */
|
||||
s->srv_addr = srv->addr;
|
||||
s->srv = srv;
|
||||
}
|
||||
else if (s->proxy->options & PR_O_BALANCE_SH) {
|
||||
struct server *srv;
|
||||
int len;
|
||||
|
||||
if (s->cli_addr.ss_family == AF_INET)
|
||||
len = 4;
|
||||
else if (s->cli_addr.ss_family == AF_INET6)
|
||||
len = 16;
|
||||
else /* unknown IP family */
|
||||
return SN_ERR_INTERNAL;
|
||||
|
||||
srv = get_server_sh(s->proxy,
|
||||
(void *)&((struct sockaddr_in *)&s->cli_addr)->sin_addr,
|
||||
len);
|
||||
s->srv_addr = srv->addr;
|
||||
s->srv = srv;
|
||||
}
|
||||
@ -6846,8 +6927,11 @@ int cfg_parse_listen(char *file, int linenum, char **args) {
|
||||
if (!strcmp(args[1], "roundrobin")) {
|
||||
curproxy->options |= PR_O_BALANCE_RR;
|
||||
}
|
||||
else if (!strcmp(args[1], "source")) {
|
||||
curproxy->options |= PR_O_BALANCE_SH;
|
||||
}
|
||||
else {
|
||||
Alert("parsing [%s:%d] : '%s' only supports 'roundrobin' option.\n", file, linenum, args[0]);
|
||||
Alert("parsing [%s:%d] : '%s' only supports 'roundrobin' and 'source' options.\n", file, linenum, args[0]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
29
tests/active-sh.cfg
Normal file
29
tests/active-sh.cfg
Normal file
@ -0,0 +1,29 @@
|
||||
# This is a test configuration.
|
||||
# It must load-balance across active servers. Check local apache logs to
|
||||
# verify :
|
||||
#
|
||||
# tail /var/log/apache/access_log
|
||||
|
||||
|
||||
global
|
||||
maxconn 100
|
||||
|
||||
listen sample1
|
||||
mode http
|
||||
option httplog
|
||||
option dontlognull
|
||||
retries 1
|
||||
redispatch
|
||||
contimeout 1000
|
||||
clitimeout 5000
|
||||
srvtimeout 5000
|
||||
maxconn 40000
|
||||
bind :8081
|
||||
balance source
|
||||
server srv1 127.0.0.1:80 cookie s1 check port 80 inter 1000 fall 1
|
||||
server srv2 127.0.0.2:80 cookie s2 check port 80 inter 1000 fall 1
|
||||
server srv3 127.0.0.3:80 cookie s3 check port 80 inter 1000 fall 1
|
||||
#server srv4 127.0.0.4:80 cookie s4 check port 80 inter 1000 fall 1
|
||||
option httpclose
|
||||
errorloc 503 /503
|
||||
|
35
tests/backup-all-sh.cfg
Normal file
35
tests/backup-all-sh.cfg
Normal file
@ -0,0 +1,35 @@
|
||||
# This is a test configuration.
|
||||
# It must load-balance across backup servers depending on the souce hash.
|
||||
# Check local apache logs to verify :
|
||||
#
|
||||
# tail /var/log/apache/access_log
|
||||
|
||||
|
||||
global
|
||||
maxconn 100
|
||||
|
||||
listen sample1
|
||||
mode http
|
||||
option httplog
|
||||
option dontlognull
|
||||
retries 1
|
||||
redispatch
|
||||
contimeout 1000
|
||||
clitimeout 5000
|
||||
srvtimeout 5000
|
||||
maxconn 40000
|
||||
bind :8081
|
||||
balance source
|
||||
option allbackups
|
||||
server srv1 127.0.0.1:80 cookie s1 check port 81 inter 1000 fall 1
|
||||
server srv2 127.0.0.2:80 cookie s2 check port 81 inter 1000 fall 1
|
||||
server srv3 127.0.0.3:80 cookie s3 check port 81 inter 1000 fall 1
|
||||
server srv4 127.0.0.4:80 cookie s4 check port 81 inter 1000 fall 1
|
||||
server bck1 127.0.1.1:80 cookie b1 check port 80 inter 1000 fall 1 backup
|
||||
server bck2 127.0.1.2:80 cookie b2 check port 80 inter 1000 fall 1 backup
|
||||
server bck3 127.0.1.3:80 cookie b3 check port 80 inter 1000 fall 1 backup
|
||||
server bck4 127.0.1.4:80 cookie b4 check port 80 inter 1000 fall 1 backup
|
||||
server bck5 127.0.1.5:80 cookie b4 check port 80 inter 1000 fall 1 backup
|
||||
option httpclose
|
||||
errorloc 503 /503
|
||||
|
34
tests/backup-second-sh.cfg
Normal file
34
tests/backup-second-sh.cfg
Normal file
@ -0,0 +1,34 @@
|
||||
# This is a test configuration.
|
||||
# It must use only the first backup server. Check local apache logs to
|
||||
# verify :
|
||||
#
|
||||
# tail /var/log/apache/access_log
|
||||
|
||||
|
||||
global
|
||||
maxconn 100
|
||||
|
||||
listen sample1
|
||||
mode http
|
||||
option httplog
|
||||
option dontlognull
|
||||
retries 1
|
||||
redispatch
|
||||
contimeout 1000
|
||||
clitimeout 5000
|
||||
srvtimeout 5000
|
||||
maxconn 40000
|
||||
bind :8081
|
||||
balance source
|
||||
server srv1 127.0.0.1:80 cookie s1 check port 81 inter 1000 fall 1
|
||||
server srv2 127.0.0.2:80 cookie s2 check port 81 inter 1000 fall 1
|
||||
server srv3 127.0.0.3:80 cookie s3 check port 81 inter 1000 fall 1
|
||||
server srv4 127.0.0.4:80 cookie s4 check port 81 inter 1000 fall 1
|
||||
server bck1 127.0.1.1:80 cookie b1 check port 81 inter 1000 fall 1 backup
|
||||
server bck2 127.0.1.2:80 cookie b2 check port 80 inter 1000 fall 1 backup
|
||||
server bck3 127.0.1.3:80 cookie b3 check port 80 inter 1000 fall 1 backup
|
||||
server bck4 127.0.1.4:80 cookie b4 check port 80 inter 1000 fall 1 backup
|
||||
server bck5 127.0.1.5:80 cookie b5 check port 80 inter 1000 fall 1 backup
|
||||
option httpclose
|
||||
errorloc 503 /503
|
||||
|
Loading…
x
Reference in New Issue
Block a user