]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] stats: add support for changing frontend's maxconn at runtime
authorWilly Tarreau <w@1wt.eu>
Tue, 2 Aug 2011 09:49:05 +0000 (11:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 2 Aug 2011 09:49:05 +0000 (11:49 +0200)
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
src/dumpstats.c

index 537ab6f7492397985f71bdbf6f1b21e010624af7..cd5f979ebd94689260219113f09710d17a20f8c9 100644 (file)
@@ -9483,6 +9483,15 @@ prompt
 quit
   Close the connection when in interactive mode.
 
+set maxconn frontend <frontend> <value>
+  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 <delay>
   Change the CLI interface timeout for current connection. This can be useful
   during long debugging sessions where the user needs to constantly inspect
index 9caebdd599f2d0ae3ec57dc9f5402d6c737d3838..9c8922609d09db0bafd65c16684607d289664d24 100644 (file)
@@ -48,6 +48,7 @@
 #include <proto/freq_ctr.h>
 #include <proto/log.h>
 #include <proto/pipe.h>
+#include <proto/protocols.h>
 #include <proto/proto_uxst.h>
 #include <proto/proxy.h>
 #include <proto/session.h>
@@ -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;
                }