[MEDIUM] default-server support

This patch implements default-server support allowing to change
default server options. It can be used in [defaults] or [backend]/[listen]
sections. Currently the following options are supported:

 - error-limit
 - fall
 - inter
 - fastinter
 - downinter
 - maxconn
 - maxqueue
 - minconn
 - on-error
 - port
 - rise
 - slowstart
 - weight
This commit is contained in:
Krzysztof Piotr Oledzki 2010-01-05 16:38:49 +01:00 committed by Willy Tarreau
parent 15514c21a2
commit c6df066980
3 changed files with 141 additions and 92 deletions

View File

@ -47,7 +47,7 @@ Summary
4.1. Proxy keywords matrix
4.2. Alphabetically sorted keywords reference
5. Server options
5. Server and default-server options
6. HTTP header manipulation
@ -724,6 +724,7 @@ capture response header - X X -
clitimeout X X X - (deprecated)
contimeout X - X X (deprecated)
cookie X - X X
default-server X - X -
default_backend - X X -
description - X X X
disabled X X X X
@ -1606,6 +1607,19 @@ cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
See also : "appsession", "balance source", "capture cookie", "server".
default-server [param*]
Change default options for a server in a backend
May be used in sections : defaults | frontend | listen | backend
yes | no | yes | yes
Arguments:
<param*> is a list of parameters for this server. The "default-server" keywords
accepts an important number of options and has a complete section
dedicated to it. Please refer to section 5 for more details.
Examples:
default-server inter 1000 weight 13
See also: "server" and section 5 about server options
default_backend <backend>
Specify the backend to use when no "use_backend" rule has been matched.
@ -3795,7 +3809,7 @@ server <name> <address>[:port] [param*]
server first 10.1.1.1:1080 cookie first check inter 1000
server second 10.1.1.2:1080 cookie second check inter 1000
See also : section 5 about server options
See also: "default-server" and section 5 about server options
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
@ -4696,19 +4710,22 @@ use_backend <backend> unless <condition>
See also: "default_backend", "tcp-request", and section 7 about ACLs.
5. Server options
5. Server and default-server options
-----------------
The "server" keyword supports a certain number of settings which are all passed
as arguments on the server line. The order in which those arguments appear does
not count, and they are all optional. Some of those settings are single words
(booleans) while others expect one or several values after them. In this case,
the values must immediately follow the setting name. All those settings must be
specified after the server's address if they are used :
The "server" and "default-server" keywords support a certain number of settings
which are all passed as arguments on the server line. The order in which those
arguments appear does not count, and they are all optional. Some of those
settings are single words (booleans) while others expect one or several values
after them. In this case, the values must immediately follow the setting name.
Except default-server, all those settings must be specified after the server's
address if they are used:
server <name> <address>[:port] [settings ...]
default-server [settings ...]
The currently supported settings are the following ones.
The currently supported settings are the following ones, the ones marked with
"[D]" are also upported for default-server.
addr <ipv4>
Using the "addr" parameter, it becomes possible to use a different IP address
@ -4747,14 +4764,14 @@ cookie <value>
the same cookie value, and it is in fact somewhat common between normal and
backup servers. See also the "cookie" keyword in backend section.
error-limit <count>
[D] error-limit <count>
If health observing is enabled, the "error-limit" parameter specifies the number
of consecutive errors that triggers event selected by the "on-error" option.
By default it is set to 10 consecutive errors.
See also the "check", "error-limit" and "on-error".
fall <count>
[D] fall <count>
The "fall" parameter states that a server will be considered as dead after
<count> consecutive unsuccessful health checks. This value defaults to 3 if
unspecified. See also the "check", "inter" and "rise" parameters.
@ -4764,9 +4781,9 @@ id <value>
the proxy. An unused ID will automatically be assigned if unset. The first
assigned value will be 1. This ID is currently only returned in statistics.
inter <delay>
fastinter <delay>
downinter <delay>
[D] inter <delay>
[D] fastinter <delay>
[D] downinter <delay>
The "inter" parameter sets the interval between two consecutive health checks
to <delay> milliseconds. If left unspecified, the delay defaults to 2000 ms.
It is also possible to use "fastinter" and "downinter" to optimize delays
@ -4793,7 +4810,7 @@ downinter <delay>
keyword. This makes sense for instance when a lot of backends use the same
servers.
maxconn <maxconn>
[D] maxconn <maxconn>
The "maxconn" parameter specifies the maximal number of concurrent
connections that will be sent to this server. If the number of incoming
concurrent requests goes higher than this value, they will be queued, waiting
@ -4803,7 +4820,7 @@ maxconn <maxconn>
which means unlimited. See also the "minconn" and "maxqueue" parameters, and
the backend's "fullconn" keyword.
maxqueue <maxqueue>
[D] maxqueue <maxqueue>
The "maxqueue" parameter specifies the maximal number of connections which
will wait in the queue for this server. If this limit is reached, next
requests will be redispatched to other servers instead of indefinitely
@ -4812,7 +4829,7 @@ maxqueue <maxqueue>
default value is "0" which means the queue is unlimited. See also the
"maxconn" and "minconn" parameters.
minconn <minconn>
[D] minconn <minconn>
When the "minconn" parameter is set, the maxconn limit becomes a dynamic
limit following the backend's load. The server will always accept at least
<minconn> connections, never more than <maxconn>, and the limit will be on
@ -4833,7 +4850,7 @@ observe <mode>
See also the "check", "on-error" and "error-limit".
on-error <mode>
[D] on-error <mode>
Select what should happen when enough consecutive errors are detected.
Currently, four modes are available:
- fastinter: force fastinter
@ -4844,7 +4861,7 @@ on-error <mode>
See also the "check", "observe" and "error-limit".
port <port>
[D] port <port>
Using the "port" parameter, it becomes possible to use a different port to
send health-checks. On some servers, it may be desirable to dedicate a port
to a specific component able to perform complex tests which are more suitable
@ -4870,12 +4887,12 @@ redir <prefix>
Example : server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
rise <count>
[D] rise <count>
The "rise" parameter states that a server will be considered as operational
after <count> consecutive successful health checks. This value defaults to 2
if unspecified. See also the "check", "inter" and "fall" parameters.
slowstart <start_time_in_ms>
[D] slowstart <start_time_in_ms>
The "slowstart" parameter for a server accepts a value in milliseconds which
indicates after how long a server which has just come back up will run at
full speed. Just as with every other time-based parameter, it can be entered
@ -4917,7 +4934,7 @@ track [<proxy>/]<server>
one. If <proxy> is omitted the current one is used. If disable-on-404 is
used, it has to be enabled on both proxies.
weight <weight>
[D] weight <weight>
The "weight" parameter is used to adjust the server's weight relative to
other servers. All servers will receive a load proportional to their weight
relative to the sum of all weights, so the higher the weight, the higher the

View File

@ -166,7 +166,7 @@ struct proxy {
struct list inspect_rules; /* inspection rules */
} tcp_req;
int acl_requires; /* Elements required to satisfy all ACLs (ACL_USE_*) */
struct server *srv; /* known servers */
struct server *srv, defsrv; /* known servers; default server configuration */
int srv_act, srv_bck; /* # of servers eligible for LB (UP|!checked) AND (enabled+weight!=0) */
struct lbprm lbprm; /* load-balancing parameters */
char *cookie_domain; /* domain used to insert the cookie */

View File

@ -811,6 +811,20 @@ void init_default_instance()
defproxy.maxconn = cfg_maxpconn;
defproxy.conn_retries = CONN_RETRIES;
defproxy.logfac1 = defproxy.logfac2 = -1; /* log disabled */
defproxy.defsrv.inter = DEF_CHKINTR;
defproxy.defsrv.fastinter = 0;
defproxy.defsrv.downinter = 0;
defproxy.defsrv.rise = DEF_RISETIME;
defproxy.defsrv.fall = DEF_FALLTIME;
defproxy.defsrv.check_port = 0;
defproxy.defsrv.maxqueue = 0;
defproxy.defsrv.minconn = 0;
defproxy.defsrv.maxconn = 0;
defproxy.defsrv.slowstart = 0;
defproxy.defsrv.onerror = DEF_HANA_ONERR;
defproxy.defsrv.consecutive_errors_limit = DEF_HANA_ERRLIMIT;
defproxy.defsrv.uweight = defproxy.defsrv.iweight = 1;
}
/*
@ -913,6 +927,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
}
/* set default values */
memcpy(&curproxy->defsrv, &defproxy.defsrv, sizeof(curproxy->defsrv));
curproxy->state = defproxy.state;
curproxy->options = defproxy.options;
curproxy->options2 = defproxy.options2;
@ -2538,14 +2554,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
goto out;
}
}
else if (!strcmp(args[0], "server")) { /* server address */
else if (!strcmp(args[0], "server") || !strcmp(args[0], "default-server")) { /* server address */
int cur_arg;
char *rport;
char *raddr;
short realport;
int do_check;
char *rport, *raddr;
short realport = 0;
int do_check = 0, defsrv = (*args[0] == 'd');
if (curproxy == &defproxy) {
if (!defsrv && curproxy == &defproxy) {
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, linenum, args[0]);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
@ -2574,6 +2589,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
goto out;
}
if (!defsrv) {
/* the servers are linked backwards first */
newsrv->next = curproxy->srv;
curproxy->srv = newsrv;
@ -2601,31 +2617,40 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
realport = atol(rport);
if (!isdigit((unsigned char)*rport))
newsrv->state |= SRV_MAPPORTS;
} else {
realport = 0;
} else
newsrv->state |= SRV_MAPPORTS;
}
newsrv->addr = *str2sa(raddr);
newsrv->addr.sin_port = htons(realport);
free(raddr);
newsrv->check_port = curproxy->defsrv.check_port;
newsrv->inter = curproxy->defsrv.inter;
newsrv->fastinter = curproxy->defsrv.fastinter;
newsrv->downinter = curproxy->defsrv.downinter;
newsrv->rise = curproxy->defsrv.rise;
newsrv->fall = curproxy->defsrv.fall;
newsrv->maxqueue = curproxy->defsrv.maxqueue;
newsrv->minconn = curproxy->defsrv.minconn;
newsrv->maxconn = curproxy->defsrv.maxconn;
newsrv->slowstart = curproxy->defsrv.slowstart;
newsrv->onerror = curproxy->defsrv.onerror;
newsrv->consecutive_errors_limit
= curproxy->defsrv.consecutive_errors_limit;
newsrv->uweight = newsrv->iweight
= curproxy->defsrv.iweight;
newsrv->curfd = -1; /* no health-check in progress */
newsrv->inter = DEF_CHKINTR;
newsrv->fastinter = 0; /* 0 => use newsrv->inter instead */
newsrv->downinter = 0; /* 0 => use newsrv->inter instead */
newsrv->rise = DEF_RISETIME;
newsrv->fall = DEF_FALLTIME;
newsrv->health = newsrv->rise; /* up, but will fall down at first failure */
newsrv->uweight = newsrv->iweight = 1;
newsrv->maxqueue = 0;
newsrv->slowstart = 0;
newsrv->onerror = DEF_HANA_ONERR;
newsrv->consecutive_errors_limit = DEF_HANA_ERRLIMIT;
cur_arg = 3;
} else {
newsrv = &curproxy->defsrv;
cur_arg = 1;
}
while (*args[cur_arg]) {
if (!strcmp(args[cur_arg], "id")) {
if (!defsrv && !strcmp(args[cur_arg], "id")) {
struct eb32_node *node;
if (!*args[cur_arg + 1]) {
@ -2656,12 +2681,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
eb32_insert(&curproxy->conf.used_server_id, &newsrv->conf.id);
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "cookie")) {
else if (!defsrv && !strcmp(args[cur_arg], "cookie")) {
newsrv->cookie = strdup(args[cur_arg + 1]);
newsrv->cklen = strlen(args[cur_arg + 1]);
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "redir")) {
else if (!defsrv && !strcmp(args[cur_arg], "redir")) {
newsrv->rdr_pfx = strdup(args[cur_arg + 1]);
newsrv->rdr_len = strlen(args[cur_arg + 1]);
cur_arg += 2;
@ -2755,7 +2780,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
newsrv->downinter = val;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "addr")) {
else if (!defsrv && !strcmp(args[cur_arg], "addr")) {
newsrv->check_addr = *str2sa(args[cur_arg + 1]);
cur_arg += 2;
}
@ -2763,7 +2788,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
newsrv->check_port = atol(args[cur_arg + 1]);
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "backup")) {
else if (!defsrv && !strcmp(args[cur_arg], "backup")) {
newsrv->state |= SRV_BACKUP;
cur_arg ++;
}
@ -2809,7 +2834,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
newsrv->slowstart = (val + 999) / 1000;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "track")) {
else if (!defsrv && !strcmp(args[cur_arg], "track")) {
if (!*args[cur_arg + 1]) {
Alert("parsing [%s:%d]: 'track' expects [<proxy>/]<server> as argument.\n",
@ -2822,12 +2847,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "check")) {
else if (!defsrv && !strcmp(args[cur_arg], "check")) {
global.maxsock++;
do_check = 1;
cur_arg += 1;
}
else if (!strcmp(args[cur_arg], "observe")) {
else if (!defsrv && !strcmp(args[cur_arg], "observe")) {
if (!strcmp(args[cur_arg + 1], "none"))
newsrv->observe = HANA_OBS_NONE;
else if (!strcmp(args[cur_arg + 1], "layer4"))
@ -2886,7 +2911,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
goto out;
}
}
else if (!strcmp(args[cur_arg], "source")) { /* address to which we bind when connecting */
else if (!defsrv && !strcmp(args[cur_arg], "source")) { /* address to which we bind when connecting */
int port_low, port_high;
if (!*args[cur_arg + 1]) {
#if defined(CONFIG_HAP_CTTPROXY) || defined(CONFIG_HAP_LINUX_TPROXY)
@ -2984,15 +3009,20 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
break;
} /* while */
}
else if (!strcmp(args[cur_arg], "usesrc")) { /* address to use outside: needs "source" first */
else if (!defsrv && !strcmp(args[cur_arg], "usesrc")) { /* address to use outside: needs "source" first */
Alert("parsing [%s:%d] : '%s' only allowed after a '%s' statement.\n",
file, linenum, "usesrc", "source");
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
else {
if (!defsrv)
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'track', 'id', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
file, linenum, newsrv->id);
else
Alert("parsing [%s:%d]: default-server only supports options 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'port', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
file, linenum);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
@ -3037,6 +3067,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
newsrv->state |= SRV_CHECKED;
}
if (!defsrv) {
if (newsrv->state & SRV_BACKUP)
curproxy->srv_bck++;
else
@ -3044,6 +3075,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
newsrv->prev_state = newsrv->state;
}
}
else if (!strcmp(args[0], "log")) { /* syslog server address */
struct logsrv logsrv;
int facility;