From a0250ba38da12775bcc829b13c063aa4e5e37b25 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 6 Jan 2008 11:22:57 +0100 Subject: [PATCH] [OPTIM] introduce global parameter "tune.maxaccept" This new parameter makes it possible to override the default number of consecutive incoming connections which can be accepted on a socket. By default it is not limited on single process mode, and limited to 8 in multi-process mode. --- doc/configuration.txt | 27 +++++++++++++++++++-------- include/types/global.h | 1 + src/cfgparse.c | 11 +++++++++++ src/client.c | 7 +------ src/haproxy.c | 7 +++++++ 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/doc/configuration.txt b/doc/configuration.txt index 1c7a058d24..ea3d342c20 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -67,8 +67,9 @@ The following keywords are supported in the "global" section : - nokqueue - nopoll - nosepoll - - tune.maxpollevents - spread-checks + - tune.maxaccept + - tune.maxpollevents * Debugging - debug @@ -212,13 +213,6 @@ nosepoll is equivalent to the command-line argument "-ds". The next polling system used will generally be "epoll". See also "nosepoll", and "nopoll". -tune.maxpollevents - Sets the maximum amount of events that can be processed at once in a call to - the polling system. The default value is adapted to the operating system. It - has been noticed that reducing it below 200 tends to slightly decrease - latency at the expense of network bandwidth, and increasing it above 200 - tends to trade latency for slightly increased bandwidth. - spread-checks <0..50, in percent> Sometimes it is desirable to avoid sending health checks to servers at exact intervals, for instance when many logical servers are located on the same @@ -226,6 +220,23 @@ spread-checks <0..50, in percent> some randomness in the check interval between 0 and +/- 50%. A value between 2 and 5 seems to show good results. The default value remains at 0. +tune.maxaccept + Sets the maximum number of consecutive accepts that a process may perform on + a single wake up. High values give higher priority to high connection rates, + while lower values give higher priority to already established connections. + This value is unlimited by default in single process mode. However, in + multi-process mode (nbproc > 1), it defaults to 8 so that when one process + wakes up, it does not take all incoming connections for itself and leaves a + part of them to other processes. Setting this value to zero or less disables + the limitation. It should normally not be needed to tweak this value. + +tune.maxpollevents + Sets the maximum amount of events that can be processed at once in a call to + the polling system. The default value is adapted to the operating system. It + has been noticed that reducing it below 200 tends to slightly decrease + latency at the expense of network bandwidth, and increasing it above 200 + tends to trade latency for slightly increased bandwidth. + 1.3) Debugging --------------- diff --git a/include/types/global.h b/include/types/global.h index 18a94b291f..16369540b1 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -63,6 +63,7 @@ struct global { struct logsrv logsrv1, logsrv2; struct { int maxpollevents; /* max number of poll events at once */ + int maxaccept; /* max number of consecutive accept() */ } tune; struct listener stats_sock; /* unix socket listener for statistics */ struct timeval stats_timeout; diff --git a/src/cfgparse.c b/src/cfgparse.c index 7b43b7e68d..655a40e634 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -307,6 +307,17 @@ int cfg_parse_global(const char *file, int linenum, char **args, int inv) } global.tune.maxpollevents = atol(args[1]); } + else if (!strcmp(args[0], "tune.maxaccept")) { + if (global.tune.maxaccept != 0) { + Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]); + return 0; + } + if (*(args[1]) == 0) { + Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]); + return -1; + } + global.tune.maxaccept = atol(args[1]); + } else if (!strcmp(args[0], "uid")) { if (global.uid != 0) { Alert("parsing [%s:%d] : user/uid already specified. Continuing.\n", file, linenum); diff --git a/src/client.c b/src/client.c index 2505db3056..cfcfb0c3f8 100644 --- a/src/client.c +++ b/src/client.c @@ -74,12 +74,7 @@ int event_accept(int fd) { struct http_txn *txn; struct task *t; int cfd; - int max_accept; - - if (global.nbproc > 1) - max_accept = 8; /* let other processes catch some connections too */ - else - max_accept = -1; + int max_accept = global.tune.maxaccept; while (p->feconn < p->maxconn && max_accept--) { struct sockaddr_storage addr; diff --git a/src/haproxy.c b/src/haproxy.c index fd7c96e6ea..f4f7b17a77 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -569,6 +569,13 @@ void init(int argc, char **argv) if (global.tune.maxpollevents <= 0) global.tune.maxpollevents = MAX_POLL_EVENTS; + if (global.tune.maxaccept <= 0) { + if (global.nbproc > 1) + global.tune.maxaccept = 8; /* leave some conns to other processes */ + else + global.tune.maxaccept = -1; /* accept all incoming conns */ + } + if (arg_mode & (MODE_DEBUG | MODE_FOREGROUND)) { /* command line debug mode inhibits configuration mode */ global.mode &= ~(MODE_DAEMON | MODE_QUIET);