Skip to content

Commit

Permalink
[MEDIUM] Implement "track [<backend>/]<server>"
Browse files Browse the repository at this point in the history
This patch implements ability to set the current state of one server
by tracking another one. It:
 - adds two variables: *tracknext, *tracked to struct server
 - implements findserver(), similar to findproxy()
 - adds "track" keyword accepting both "proxy/server" and "server" (assuming current proxy)
 - verifies if both checks and tracking is not enabled at the same time
 - changes set_server_down() to notify tracking server
 - creates set_server_up(), set_server_disabled(), set_server_enabled() by
   moving the code from process_chk() and adding notifications
 - changes stats to show a name of tracked server instead of Chk/Dwn/Dwntime(html)
   or by adding new variable (csv)

Changes from the previuos version:
 - it is possibile to track independently of the declaration order
 - one extra comma bug is fixed
 - new condition to check if there is no disable-on-404 inconsistency
  • Loading branch information
Krzysztof Piotr Oledzki authored and wtarreau committed Feb 27, 2008
1 parent f14358b commit c8b16fc
Show file tree
Hide file tree
Showing 8 changed files with 332 additions and 114 deletions.
3 changes: 0 additions & 3 deletions TODO
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ TODO for 1.3
filters and backend, on which every entity could rely. filters and backend, on which every entity could rely.
- implement 'on uri <uri> <proxy>', 'on host <host> <proxy>' - implement 'on uri <uri> <proxy>', 'on host <host> <proxy>'
- remove the first now useless hop in hdr_idx - remove the first now useless hop in hdr_idx
- implement "track XXX.YYY" for each server as an alternative to
health checks. This will automatically set the server state to
the same as server YYY of proxy XXX.
- balance on URI hash (specify length or depth) - balance on URI hash (specify length or depth)
- balance on any header hash (eg: host) - balance on any header hash (eg: host)
- balance with redirections to real servers - balance with redirections to real servers
Expand Down
7 changes: 7 additions & 0 deletions doc/configuration.txt
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3893,6 +3893,13 @@ source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
as the backend "source" keyword, except that it only applies to the server as the backend "source" keyword, except that it only applies to the server
referencing it. Please consult the "source" keyword for details. referencing it. Please consult the "source" keyword for details.


track [<proxy>/]<server>
This option enables ability to set the current state of the server by
tracking another one. Only a server with checks enabled can be tracked
so it is not possible for example to track a server that tracks another
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> weight <weight>
The "weight" parameter is used to adjust the server's weight relative to 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 other servers. All servers will receive a load proportional to their weight
Expand Down
1 change: 1 addition & 0 deletions include/proto/proxy.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void listen_proxies(void);
const char *proxy_cap_str(int cap); const char *proxy_cap_str(int cap);
const char *proxy_mode_str(int mode); const char *proxy_mode_str(int mode);
struct proxy *findproxy(const char *name, int mode, int cap); struct proxy *findproxy(const char *name, int mode, int cap);
struct server *findserver(const struct proxy *px, const char *name);
int proxy_parse_timeout(const char **args, struct proxy *proxy, int proxy_parse_timeout(const char **args, struct proxy *proxy,
struct proxy *defpx, char *err, int errlen); struct proxy *defpx, char *err, int errlen);


Expand Down
2 changes: 2 additions & 0 deletions include/types/server.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ struct server {
struct sockaddr_in tproxy_addr; /* non-local address we want to bind to for connect() */ struct sockaddr_in tproxy_addr; /* non-local address we want to bind to for connect() */
#endif #endif


struct server *tracknext, *tracked; /* next server in a tracking list, tracked server */
char *trackit; /* temporary variable to make assignment deferrable */
struct sockaddr_in check_addr; /* the address to check, if different from <addr> */ struct sockaddr_in check_addr; /* the address to check, if different from <addr> */
short check_port; /* the port to use for the health checks */ short check_port; /* the port to use for the health checks */
int health; /* 0->rise-1 = bad; rise->rise+fall-1 = good */ int health; /* 0->rise-1 = bad; rise->rise+fall-1 = good */
Expand Down
80 changes: 79 additions & 1 deletion src/cfgparse.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1625,6 +1625,18 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
newsrv->slowstart = (val + 999) / 1000; newsrv->slowstart = (val + 999) / 1000;
cur_arg += 2; cur_arg += 2;
} }
else if (!strcmp(args[cur_arg], "track")) {

if (!*args[cur_arg + 1]) {
Alert("parsing [%s:%d]: 'track' expects [<proxy>/]<server> as argument.\n",
file, linenum);
return -1;
}

newsrv->trackit = strdup(args[cur_arg + 1]);

cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "check")) { else if (!strcmp(args[cur_arg], "check")) {
global.maxsock++; global.maxsock++;
do_check = 1; do_check = 1;
Expand Down Expand Up @@ -1684,13 +1696,19 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv)
return -1; return -1;
} }
else { else {
Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n", Alert("parsing [%s:%d] : server %s only supports options 'backup', 'cookie', 'redir', 'check', 'track', 'inter', 'fastinter', 'downinter', 'rise', 'fall', 'addr', 'port', 'source', 'minconn', 'maxconn', 'maxqueue', 'slowstart' and 'weight'.\n",
file, linenum, newsrv->id); file, linenum, newsrv->id);
return -1; return -1;
} }
} }


if (do_check) { if (do_check) {
if (newsrv->trackit) {
Alert("parsing [%s:%d]: unable to enable checks and tracking at the same time!\n",
file, linenum);
return -1;
}

if (!newsrv->check_port && newsrv->check_addr.sin_port) if (!newsrv->check_port && newsrv->check_addr.sin_port)
newsrv->check_port = newsrv->check_addr.sin_port; newsrv->check_port = newsrv->check_addr.sin_port;


Expand Down Expand Up @@ -2913,6 +2931,7 @@ int readcfgfile(const char *file)
/* /*
* If this server supports a maxconn parameter, it needs a dedicated * If this server supports a maxconn parameter, it needs a dedicated
* tasks to fill the emptied slots when a connection leaves. * tasks to fill the emptied slots when a connection leaves.
* Also, resolve deferred tracking dependency if needed.
*/ */
newsrv = curproxy->srv; newsrv = curproxy->srv;
while (newsrv != NULL) { while (newsrv != NULL) {
Expand Down Expand Up @@ -2950,6 +2969,65 @@ int readcfgfile(const char *file)
tv_eternity(&t->expire); tv_eternity(&t->expire);
task_queue(t); task_queue(t);
} }

if (newsrv->trackit) {
struct proxy *px;
struct server *srv;
char *pname, *sname;

pname = newsrv->trackit;
sname = strrchr(pname, '/');

if (sname)
*sname++ = '\0';
else {
sname = pname;
pname = NULL;
}

if (pname) {
px = findproxy(pname, curproxy->mode, PR_CAP_BE);
if (!px) {
Alert("parsing %s, %s '%s', server '%s': unable to find required proxy '%s' for tracking.\n",
file, proxy_type_str(curproxy), curproxy->id,
newsrv->id, pname);
return -1;
}
} else
px = curproxy;

srv = findserver(px, sname);
if (!srv) {
Alert("parsing %s, %s '%s', server '%s': unable to find required server '%s' for tracking.\n",
file, proxy_type_str(curproxy), curproxy->id,
newsrv->id, sname);
return -1;
}

if (!(srv->state & SRV_CHECKED)) {
Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for "
"tracing as it does not have checks enabled.\n",
file, proxy_type_str(curproxy), curproxy->id,
newsrv->id, px->id, srv->id);
return -1;
}

if (curproxy != px &&
(curproxy->options & PR_O_DISABLE404) != (px->options & PR_O_DISABLE404)) {
Alert("parsing %s, %s '%s', server '%s': unable to use %s/%s for"
"tracing: disable-on-404 option inconsistency.\n",
file, proxy_type_str(curproxy), curproxy->id,
newsrv->id, px->id, srv->id);
return -1;
}

newsrv->tracked = srv;
newsrv->tracknext = srv->tracknext;
srv->tracknext = newsrv;

free(newsrv->trackit);
}

newsrv = newsrv->next; newsrv = newsrv->next;
} }


Expand Down
Loading

0 comments on commit c8b16fc

Please sign in to comment.