From: Olivier Houchard Date: Mon, 18 Feb 2019 15:41:17 +0000 (+0100) Subject: BUG/MEDIUM: servers: Add a per-thread counter of idle connections. X-Git-Tag: v2.0-dev1~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f131481a0af79037bc6616edf450ae81d80084d7;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: servers: Add a per-thread counter of idle connections. 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. --- diff --git a/include/proto/connection.h b/include/proto/connection.h index 1dc0512f41..45b8a8a537 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -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); diff --git a/include/proto/server.h b/include/proto/server.h index 51d1015e98..9467f697a9 100644 --- a/include/proto/server.h +++ b/include/proto/server.h @@ -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])) && diff --git a/include/types/server.h b/include/types/server.h index e4371af008..eae7d450d1 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -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 */ diff --git a/src/backend.c b/src/backend.c index 3c752a273b..d15020aa61 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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]); diff --git a/src/cfgparse.c b/src/cfgparse.c index 59ba773768..fde3097e89 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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", diff --git a/src/haproxy.c b/src/haproxy.c index 7c434b361f..50133fb1e7 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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; diff --git a/src/server.c b/src/server.c index 312aa1994c..4068255e5c 100644 --- a/src/server.c +++ b/src/server.c @@ -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;