]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: config: add a new tune.idle-pool.shared global setting.
authorWilly Tarreau <w@1wt.eu>
Wed, 1 Jul 2020 16:49:24 +0000 (18:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 1 Jul 2020 17:07:37 +0000 (19:07 +0200)
Enables ('on') or disables ('off') sharing of idle connection pools between
threads for a same server. The default is to share them between threads in
order to minimize the number of persistent connections to a server, and to
optimize the connection reuse rate. But to help with debugging or when
suspecting a bug in HAProxy around connection reuse, it can be convenient to
forcefully disable this idle pool sharing between multiple threads, and force
this option to "off". The default is on.

This could have been nice to have during the idle connections debugging,
but it's not too late to add it!

doc/configuration.txt
include/haproxy/global-t.h
src/backend.c
src/haproxy.c
src/server.c

index dd166e775c4a507b20cb40a9e09dd89ec0abb2ab..89b985fb8026aabd03c9a29cd6f5c549571d119f 100644 (file)
@@ -682,6 +682,7 @@ The following keywords are supported in the "global" section :
    - tune.http.cookielen
    - tune.http.logurilen
    - tune.http.maxhdr
+   - tune.idle-pool.shared
    - tune.idletimer
    - tune.lua.forced-yield
    - tune.lua.maxmem
@@ -1949,6 +1950,15 @@ tune.http.maxhdr <number>
   1..32767. Keep in mind that each new header consumes 32bits of memory for
   each session, so don't push this limit too high.
 
+tune.idle-pool.shared { on | off }
+  Enables ('on') or disables ('off') sharing of idle connection pools between
+  threads for a same server. The default is to share them between threads in
+  order to minimize the number of persistent connections to a server, and to
+  optimize the connection reuse rate. But to help with debugging or when
+  suspecting a bug in HAProxy around connection reuse, it can be convenient to
+  forcefully disable this idle pool sharing between multiple threads, and force
+  this option to "off". The default is on.
+
 tune.idletimer <timeout>
   Sets the duration after which haproxy will consider that an empty buffer is
   probably associated with an idle stream. This is used to optimally adjust
index 0da246ddee478e5122b7a3a9ce76cca8f4cc6462..677d98f51a34972b74358dc1440f33566b12edea 100644 (file)
@@ -68,6 +68,7 @@
 #define GTUNE_INSECURE_SETUID    (1<<17)
 #define GTUNE_FD_ET              (1<<18)
 #define GTUNE_SCHED_LOW_LATENCY  (1<<19)
+#define GTUNE_IDLE_POOL_SHARED   (1<<20)
 
 /* SSL server verify mode */
 enum {
index 0b4cb4c9383d0e94afd17ee1bda2a49567c00e6d..f87940be8d913b84c8c211fad42afce414bebd27 100644 (file)
@@ -1107,6 +1107,10 @@ static struct connection *conn_backend_get(struct server *srv, int is_safe)
        if (conn)
                goto done;
 
+       /* pool sharing globally disabled ? */
+       if (!(global.tune.options & GTUNE_IDLE_POOL_SHARED))
+               goto done;
+
        /* Are we allowed to pick from another thread ? We'll still try
         * it if we're running low on FDs as we don't want to create
         * extra conns in this case, otherwise we can give up if we have
index c8c869a6fd158638c4175558dd447ec03dc9942a..e733d454df16256fc7503323322f05e521a449bd 100644 (file)
@@ -1788,6 +1788,9 @@ static void init(int argc, char **argv)
 #if defined(SO_REUSEPORT)
        global.tune.options |= GTUNE_USE_REUSEPORT;
 #endif
+#ifdef USE_THREAD
+       global.tune.options |= GTUNE_IDLE_POOL_SHARED;
+#endif
 
        pid = getpid();
        progname = *argv;
index ac32e1c250f28ed0c2e90e56d45aadd6c4a542e0..a016b7bd909b766b435b35dd6990b68c31a9549a 100644 (file)
@@ -5333,6 +5333,25 @@ remove:
        return task;
 }
 
+/* config parser for global "tune.idle-pool.shared", accepts "on" or "off" */
+static int cfg_parse_idle_pool_shared(char **args, int section_type, struct proxy *curpx,
+                                      struct proxy *defpx, const char *file, int line,
+                                      char **err)
+{
+       if (too_many_args(1, args, err, NULL))
+               return -1;
+
+       if (strcmp(args[1], "on") == 0)
+               global.tune.options |= GTUNE_IDLE_POOL_SHARED;
+       else if (strcmp(args[1], "off") == 0)
+               global.tune.options &= ~GTUNE_IDLE_POOL_SHARED;
+       else {
+               memprintf(err, "'%s' expects either 'on' or 'off' but got '%s'.", args[0], args[1]);
+               return -1;
+       }
+       return 0;
+}
+
 /* config parser for global "tune.pool-{low,high}-fd-ratio" */
 static int cfg_parse_pool_fd_ratio(char **args, int section_type, struct proxy *curpx,
                                    struct proxy *defpx, const char *file, int line,
@@ -5360,6 +5379,7 @@ static int cfg_parse_pool_fd_ratio(char **args, int section_type, struct proxy *
 
 /* config keyword parsers */
 static struct cfg_kw_list cfg_kws = {ILH, {
+       { CFG_GLOBAL, "tune.idle-pool.shared",       cfg_parse_idle_pool_shared },
        { CFG_GLOBAL, "tune.pool-high-fd-ratio",     cfg_parse_pool_fd_ratio },
        { CFG_GLOBAL, "tune.pool-low-fd-ratio",      cfg_parse_pool_fd_ratio },
        { 0, NULL, NULL }