[MEDIUM] stats: add the "set weight" command

It is now possible to change a server's weight from the stats socket.
Just use "set weight <back>/<serv> <weight>".
This commit is contained in:
Willy Tarreau 2009-10-10 19:30:08 +02:00
parent 38338fa0a0
commit 4483d43c66
2 changed files with 97 additions and 1 deletions

View File

@ -6876,6 +6876,20 @@ get weight <backend>/<server>
the one that appears in the configuration file. Both are normally equal the one that appears in the configuration file. Both are normally equal
unless the current weight has been changed. unless the current weight has been changed.
set weight <backend>/<server> <weight>[%]
Change a server's weight to the value passed in argument. If the value ends
with the '%' sign, then the new weight will be relative to the initially
configured weight. Relative weights are only permitted between 0 and 100%,
and absolute weights are permitted between 0 and 256. Servers which are part
of a farm running a static load-balancing algorithm have stricter limitations
because the weight cannot change once set. Thus for these servers, the only
accepted values are 0 and 100% (or 0 and the initial weight). Changes take
effect immediately, though certain LB algorithms require a certain amount of
requests to consider changes. A typical usage of this command is to disable
a server during an update by setting its weight to zero, then to enable it
again after the update by setting it back to 100%. This command is restricted
and can only be issued on sockets configured for level "admin".
/* /*
* Local variables: * Local variables:

View File

@ -63,6 +63,7 @@ const char stats_sock_usage_msg[] =
" show errors : report last request and response errors for each proxy\n" " show errors : report last request and response errors for each proxy\n"
" show sess : report the list of current sessions\n" " show sess : report the list of current sessions\n"
" get weight : report a server's current weight\n" " get weight : report a server's current weight\n"
" set weight : change a server's weight\n"
""; "";
const char stats_permission_denied_msg[] = const char stats_permission_denied_msg[] =
@ -412,7 +413,88 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
return 0; return 0;
} }
} }
else { /* not "show" nor "clear" nor "get" */ else if (strcmp(args[0], "set") == 0) {
if (strcmp(args[1], "weight") == 0) {
struct proxy *px;
struct server *sv;
int w;
if (s->listener->perm.ux.level < ACCESS_LVL_ADMIN) {
buffer_feed(si->ib, stats_permission_denied_msg);
return 1;
}
/* split "backend/server" and make <line> point to server */
for (line = args[2]; *line; line++)
if (*line == '/') {
*line++ = '\0';
break;
}
if (!*line || !*args[3]) {
buffer_feed(si->ib, "Require 'backend/server' and 'weight' or 'weight%'.\n");
return 1;
}
if (!get_backend_server(args[2], line, &px, &sv)) {
if (!px)
buffer_feed(si->ib, "No such backend.\n");
else
buffer_feed(si->ib, "No such server.\n");
return 1;
}
/* if the weight is terminated with '%', it is set relative to
* the initial weight, otherwise it is absolute.
*/
w = atoi(args[3]);
if (strchr(args[3], '%') != NULL) {
if (w < 0 || w > 100) {
buffer_feed(si->ib, "Relative weight can only be set between 0 and 100% inclusive.\n");
return 1;
}
w = sv->iweight * w / 100;
}
else {
if (w < 0 || w > 256) {
buffer_feed(si->ib, "Absolute weight can only be between 0 and 256 inclusive.\n");
return 1;
}
}
if (w && w != sv->iweight && !(px->lbprm.algo & BE_LB_PROP_DYN)) {
buffer_feed(si->ib, "Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.\n");
return 1;
}
sv->uweight = w;
if (px->lbprm.algo & BE_LB_PROP_DYN) {
/* we must take care of not pushing the server to full throttle during slow starts */
if ((sv->state & SRV_WARMINGUP) && (px->lbprm.algo & BE_LB_PROP_DYN))
sv->eweight = (BE_WEIGHT_SCALE * (now.tv_sec - sv->last_change) + sv->slowstart - 1) / sv->slowstart;
else
sv->eweight = BE_WEIGHT_SCALE;
sv->eweight *= sv->uweight;
} else {
sv->eweight = sv->uweight;
}
/* static LB algorithms are a bit harder to update */
if (px->lbprm.update_server_eweight)
px->lbprm.update_server_eweight(sv);
else if (sv->eweight)
px->lbprm.set_server_status_up(sv);
else
px->lbprm.set_server_status_down(sv);
return 1;
}
else { /* not "set weight" */
return 0;
}
}
else { /* not "show" nor "clear" nor "get" nor "set" */
return 0; return 0;
} }
return 1; return 1;