From 2a0f4d27a4a63ddb3788f3277f20ba15dc709f34 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 2 Aug 2011 11:49:05 +0200 Subject: [PATCH] [MEDIUM] stats: add support for changing frontend's maxconn at runtime The new "set maxconn frontend XXX" statement on the stats socket allows the admin to change a frontend's maxconn value. If some connections are queued, they will immediately be accepted up to the new limit. If the limit is lowered, new connections acceptation might be delayed. This can be used to temporarily reduce or increase the impact of a specific frontend's traffic on the whole process. --- doc/configuration.txt | 9 +++++++ src/dumpstats.c | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/doc/configuration.txt b/doc/configuration.txt index 537ab6f74..cd5f979eb 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -9483,6 +9483,15 @@ prompt quit Close the connection when in interactive mode. +set maxconn frontend + Dynamically change the specified frontend's maxconn setting. Any non-null + positive value is allowed, but setting values larger than the global maxconn + does not make much sense. If the limit is increased and connections were + pending, they will immediately be accepted. If it is lowered to a value below + the current number of connections, new connections acceptation will be + delayed until the threshold is reached. The frontend might be specified by + either its name or its numeric ID prefixed with a sharp ('#'). + set timeout cli Change the CLI interface timeout for current connection. This can be useful during long debugging sessions where the user needs to constantly inspect diff --git a/src/dumpstats.c b/src/dumpstats.c index 9caebdd59..9c8922609 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ static const char stats_sock_usage_msg[] = " set timeout : change a timeout setting\n" " disable server : set a server in maintenance mode\n" " enable server : re-enable a server that was previously in maintenance mode\n" + " set maxconn : change a maxconn setting\n" ""; static const char stats_permission_denied_msg[] = @@ -958,6 +960,66 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) return 1; } } + else if (strcmp(args[1], "maxconn") == 0) { + if (strcmp(args[2], "frontend") == 0) { + struct proxy *px; + struct listener *l; + int v; + + if (s->listener->perm.ux.level < ACCESS_LVL_ADMIN) { + si->applet.ctx.cli.msg = stats_permission_denied_msg; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + if (!*args[3]) { + si->applet.ctx.cli.msg = "Frontend name expected.\n"; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + px = findproxy(args[3], PR_CAP_FE); + if (!px) { + si->applet.ctx.cli.msg = "No such frontend.\n"; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + if (!*args[4]) { + si->applet.ctx.cli.msg = "Integer value expected.\n"; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + v = atoi(args[4]); + /* check for unlimited values, we restore default setting (cfg_maxpconn) */ + if (v < 1) { + si->applet.ctx.cli.msg = "Value out of range.\n"; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + /* OK, the value is fine, so we assign it to the proxy and to all of + * its listeners. The blocked ones will be dequeued. + */ + px->maxconn = v; + for (l = px->listen; l != NULL; l = l->next) { + l->maxconn = v; + if (l->state == LI_FULL) + resume_listener(l); + } + + if (px->maxconn > px->feconn && !LIST_ISEMPTY(&s->fe->listener_queue)) + dequeue_all_listeners(&s->fe->listener_queue); + + return 1; + } + else { + si->applet.ctx.cli.msg = "'set maxconn' only supports 'frontend'.\n"; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + } else { /* unknown "set" parameter */ return 0; }