mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-14 07:24:32 +00:00
[MEDIUM] implement bind-process to limit service presence by process
The "bind-process" keyword lets the admin select which instances may run on which process (in multi-process mode). It makes it easier to more evenly distribute the load across multiple processes by avoiding having too many listen to the same IP:ports.
This commit is contained in:
parent
c76721da57
commit
0b9c02c861
@ -523,6 +523,7 @@ appsession - - X X
|
||||
backlog X X X -
|
||||
balance X - X X
|
||||
bind - X X -
|
||||
bind-process X X X X
|
||||
block - X X X
|
||||
capture cookie - X X -
|
||||
capture request header - X X -
|
||||
@ -903,6 +904,57 @@ bind [<address>]:<port> [, ...] transparent
|
||||
See also : "source".
|
||||
|
||||
|
||||
bind-process [ all | odd | even | <number 1-32> ] ...
|
||||
Limit visibility of an instance to a certain set of processes numbers.
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
yes | yes | yes | yes
|
||||
Arguments :
|
||||
all All process will see this instance. This is the default. It
|
||||
may be used to override a default value.
|
||||
|
||||
odd This instance will be enabled on processes 1,3,5,...31. This
|
||||
option may be combined with other numbers.
|
||||
|
||||
even This instance will be enabled on processes 2,4,6,...32. This
|
||||
option may be combined with other numbers. Do not use it
|
||||
with less than 2 processes otherwise some instances might be
|
||||
missing from all processes.
|
||||
|
||||
number The instance will be enabled on this process number, between
|
||||
1 and 32. You must be careful not to reference a process
|
||||
number greater than the configured global.nbproc, otherwise
|
||||
some instances might be missing from all processes.
|
||||
|
||||
This keyword limits binding of certain instances to certain processes. This
|
||||
is useful in order not to have too many processes listening to the same
|
||||
ports. For instance, on a dual-core machine, it might make sense to set
|
||||
'nbproc 2' in the global section, then distributes the listeners among 'odd'
|
||||
and 'even' instances.
|
||||
|
||||
At the moment, it is not possible to reference more than 32 processes using
|
||||
this keyword, but this should be more than enough for most setups. Please
|
||||
note that 'all' really means all processes and is not limited to the first
|
||||
32.
|
||||
|
||||
If some backends are referenced by frontends bound to other processes, the
|
||||
backend automatically inherits the frontend's processes.
|
||||
|
||||
Example :
|
||||
listen app_ip1
|
||||
bind 10.0.0.1:80
|
||||
bind_process odd
|
||||
|
||||
listen app_ip2
|
||||
bind 10.0.0.2:80
|
||||
bind_process even
|
||||
|
||||
listen management
|
||||
bind 10.0.0.3:80
|
||||
bind_process 1 2 3 4
|
||||
|
||||
See also : "nbproc" in global section.
|
||||
|
||||
|
||||
block { if | unless } <condition>
|
||||
Block a layer 7 request if/unless a condition is matched
|
||||
May be used in sections : defaults | frontend | listen | backend
|
||||
|
@ -258,6 +258,7 @@ struct proxy {
|
||||
int uuid; /* universally unique proxy ID, used for SNMP */
|
||||
int next_svid; /* next server-id, used for SNMP */
|
||||
unsigned int backlog; /* force the frontend's listen backlog */
|
||||
unsigned int bind_proc; /* bitmask of processes using this proxy. 0 = all. */
|
||||
};
|
||||
|
||||
struct switching_rule {
|
||||
|
@ -668,6 +668,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
||||
curproxy->state = defproxy.state;
|
||||
curproxy->options = defproxy.options;
|
||||
curproxy->options2 = defproxy.options2;
|
||||
curproxy->bind_proc = defproxy.bind_proc;
|
||||
curproxy->lbprm.algo = defproxy.lbprm.algo;
|
||||
curproxy->except_net = defproxy.except_net;
|
||||
curproxy->except_mask = defproxy.except_mask;
|
||||
@ -930,6 +931,39 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
|
||||
else if (!strcmp(args[0], "enabled")) { /* enables this proxy (used to revert a disabled default) */
|
||||
curproxy->state = PR_STNEW;
|
||||
}
|
||||
else if (!strcmp(args[0], "bind-process")) { /* enable this proxy only on some processes */
|
||||
int cur_arg = 1;
|
||||
unsigned int set = 0;
|
||||
|
||||
while (*args[cur_arg]) {
|
||||
int u;
|
||||
if (strcmp(args[cur_arg], "all") == 0) {
|
||||
set = 0;
|
||||
break;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "odd") == 0) {
|
||||
set |= 0x55555555;
|
||||
}
|
||||
else if (strcmp(args[cur_arg], "even") == 0) {
|
||||
set |= 0xAAAAAAAA;
|
||||
}
|
||||
else {
|
||||
u = str2uic(args[cur_arg]);
|
||||
if (u < 1 || u > 32) {
|
||||
Alert("parsing [%s:%d]: %s expects 'all', 'odd', 'even', or process numbers from 1 to 32.\n",
|
||||
file, linenum, args[0]);
|
||||
return -1;
|
||||
}
|
||||
if (u > global.nbproc) {
|
||||
Warning("parsing [%s:%d]: %s references process number higher than global.nbproc.\n",
|
||||
file, linenum, args[0]);
|
||||
}
|
||||
set |= 1 << (u - 1);
|
||||
}
|
||||
cur_arg++;
|
||||
}
|
||||
curproxy->bind_proc = set;
|
||||
}
|
||||
else if (!strcmp(args[0], "acl")) { /* add an ACL */
|
||||
if (curproxy == &defproxy) {
|
||||
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
|
||||
@ -3168,6 +3202,11 @@ int readcfgfile(const char *file)
|
||||
} else {
|
||||
free(curproxy->defbe.name);
|
||||
curproxy->defbe.be = target;
|
||||
/* we force the backend to be present on at least all of
|
||||
* the frontend's processes.
|
||||
*/
|
||||
target->bind_proc = curproxy->bind_proc ?
|
||||
(target->bind_proc | curproxy->bind_proc) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3193,6 +3232,11 @@ int readcfgfile(const char *file)
|
||||
} else {
|
||||
free((void *)exp->replace);
|
||||
exp->replace = (const char *)target;
|
||||
/* we force the backend to be present on at least all of
|
||||
* the frontend's processes.
|
||||
*/
|
||||
target->bind_proc = curproxy->bind_proc ?
|
||||
(target->bind_proc | curproxy->bind_proc) : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3214,6 +3258,11 @@ int readcfgfile(const char *file)
|
||||
} else {
|
||||
free((void *)rule->be.name);
|
||||
rule->be.backend = target;
|
||||
/* we force the backend to be present on at least all of
|
||||
* the frontend's processes.
|
||||
*/
|
||||
target->bind_proc = curproxy->bind_proc ?
|
||||
(target->bind_proc | curproxy->bind_proc) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1106,6 +1106,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (global.mode & MODE_DAEMON) {
|
||||
struct proxy *px;
|
||||
int ret = 0;
|
||||
int proc;
|
||||
|
||||
@ -1131,6 +1132,16 @@ int main(int argc, char **argv)
|
||||
free(global.pidfile);
|
||||
global.pidfile = NULL;
|
||||
|
||||
/* we might have to unbind some proxies from some processes */
|
||||
px = proxy;
|
||||
while (px != NULL) {
|
||||
if (px->bind_proc && px->state != PR_STSTOPPED) {
|
||||
if (!(px->bind_proc & (1 << proc)))
|
||||
stop_proxy(px);
|
||||
}
|
||||
px = px->next;
|
||||
}
|
||||
|
||||
if (proc == global.nbproc)
|
||||
exit(0); /* parent must leave */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user