]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: servers: Add a per-thread counter of idle connections.
authorOlivier Houchard <ohouchard@haproxy.com>
Mon, 18 Feb 2019 15:41:17 +0000 (16:41 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 21 Feb 2019 18:07:45 +0000 (19:07 +0100)
Add a per-thread counter of idling connections, and use it to determine
how many connections we should kill after the timeout, instead of using
the global counter, or we're likely to just kill most of the connections.

This should be backported to 1.9.

include/proto/connection.h
include/proto/server.h
include/types/server.h
src/backend.c
src/cfgparse.c
src/haproxy.c
src/server.c

index 1dc0512f417cecc72d52a8887e4ddd09279faef9..45b8a8a5379b3cc76bd1f5270b4ee64c8759e97c 100644 (file)
@@ -694,6 +694,7 @@ static inline void conn_free(struct connection *conn)
        if (conn->idle_time > 0) {
                struct server *srv = __objt_server(conn->target);
                HA_ATOMIC_SUB(&srv->curr_idle_conns, 1);
+               srv->curr_idle_thr[tid]--;
        }
 
        conn_force_unsubscribe(conn);
index 51d1015e98f8312e4dd019e5e30707b893dbacea..9467f697a92a80bc72daf358621873fa6216e2d0 100644 (file)
@@ -253,6 +253,7 @@ static inline int srv_add_to_idle_list(struct server *srv, struct connection *co
                }
                LIST_DEL(&conn->list);
                LIST_ADDQ(&srv->idle_orphan_conns[tid], &conn->list);
+               srv->curr_idle_thr[tid]++;
 
                conn->idle_time = now_ms;
                if (!(task_in_wq(srv->idle_task[tid])) &&
index e4371af0081bf12dd9d93f19a815f0e2828e1574..eae7d450d1e912d8f667979f548affdd045756d7 100644 (file)
@@ -225,6 +225,7 @@ struct server {
        unsigned int pool_purge_delay;          /* Delay before starting to purge the idle conns pool */
        unsigned int max_idle_conns;            /* Max number of connection allowed in the orphan connections list */
        unsigned int curr_idle_conns;           /* Current number of orphan idling connections */
+       unsigned int *curr_idle_thr;            /* Current number of orphan idling connections per thread */
        int max_reuse;                          /* Max number of requests on a same connection */
        struct task **idle_task;                /* task responsible for cleaning idle orphan connections */
        struct task *warmup;                    /* the task dedicated to the warmup when slowstart is set */
index 3c752a273b999492a5f4f732937c737d7d6bf26b..d15020aa6141dd1a65e34a87da3123547b75d072 100644 (file)
@@ -1344,6 +1344,7 @@ int connect_server(struct stream *s)
                LIST_DEL(&srv_conn->list);
                srv_conn->idle_time = 0;
                HA_ATOMIC_SUB(&srv->curr_idle_conns, 1);
+               srv->curr_idle_thr[tid]--;
                LIST_ADDQ(&srv->idle_conns[tid], &srv_conn->list);
                if (LIST_ISEMPTY(&srv->idle_orphan_conns[tid]))
                        task_unlink_wq(srv->idle_task[tid]);
index 59ba773768fe6e95d73d5166cada19c943cc7e2c..fde3097e8911c6aa6fe8a4362bdc11731f21d129 100644 (file)
@@ -3593,6 +3593,9 @@ out_uri_auth_compat:
                                        newsrv->idle_task[i]->process = srv_cleanup_idle_connections;
                                        newsrv->idle_task[i]->context = newsrv;
                                }
+                               newsrv->curr_idle_thr = calloc(global.nbthread, sizeof(int));
+                               if (!newsrv->curr_idle_thr)
+                                       goto err;
                                continue;
                        err:
                                ha_alert("parsing [%s:%d] : failed to allocate idle connection tasks for server '%s'.\n",
index 7c434b361f6d6f901b220c50ecf6014f6f2f1dca..50133fb1e7bd5d9892d00a4432de2beeca99bb27 100644 (file)
@@ -2436,6 +2436,7 @@ void deinit(void)
                        free(s->priv_conns);
                        free(s->safe_conns);
                        free(s->idle_orphan_conns);
+                       free(s->curr_idle_thr);
                        if (s->idle_task) {
                                int i;
 
index 312aa1994c7bf2f314391af112d4d5fc859559dd..4068255e5c918f6e73406265f6ed6fdc2bfc4bc1 100644 (file)
@@ -5309,7 +5309,7 @@ struct task *srv_cleanup_idle_connections(struct task *task, void *context, unsi
 {
        struct server *srv = context;
        struct connection *conn, *conn_back;
-       unsigned int to_destroy = srv->curr_idle_conns / 2 + (srv->curr_idle_conns & 1);
+       unsigned int to_destroy = srv->curr_idle_thr[tid] / 2 + (srv->curr_idle_thr[tid] & 1);
        unsigned int i = 0;