From: Willy Tarreau Date: Tue, 4 Aug 2015 18:45:52 +0000 (+0200) Subject: MAJOR: backend: initial work towards connection reuse X-Git-Tag: v1.6-dev4~110 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8dff998b91bb45f36ef04c63ab5480b88f246e74;p=thirdparty%2Fhaproxy.git MAJOR: backend: initial work towards connection reuse In connect_server(), if we don't have a connection attached to the stream-int, we first look into the server's idle_conns list and we pick the first one there, we detach it from its owner if it had one. If we used to have a connection, we close it. This mechanism works well but doesn't scale : as servers increase, the likeliness that the connection attached to the stream interface doesn't match the server and gets closed increases. --- diff --git a/src/backend.c b/src/backend.c index 3c00acfd66..b31061a239 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1034,6 +1034,33 @@ int connect_server(struct stream *s) if (srv_conn) reuse = s->target == srv_conn->target; + if (srv && !reuse) { + if (srv_conn) { + srv_conn->owner = NULL; + si_release_endpoint(&s->si[1]); + srv_conn = NULL; + } + + if ((s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_ALWS && + !LIST_ISEMPTY(&srv->idle_conns)) { + /* We're going to have to pick the first connection + * from this pool and use it for our purposes. We may + * have to get rid of the current idle connection. It + * may move to another pool, but we know we're not + * interested in it. + */ + /* pick first connection. We know there's at least one */ + srv_conn = LIST_ELEM(srv->idle_conns.n, struct connection *, list); + + LIST_DEL(&srv_conn->list); + LIST_INIT(&srv_conn->list); + + si_detach_endpoint(srv_conn->owner); + si_attach_conn(&s->si[1], srv_conn); + reuse = 1; + } + } + if (reuse) { /* Disable connection reuse if a dynamic source is used. * As long as we don't share connections between servers, diff --git a/src/proto_http.c b/src/proto_http.c index fb831b9833..02ff485d44 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -5189,7 +5189,13 @@ void http_end_txn_clean_session(struct stream *s) /* we're in keep-alive with an idle connection, monitor it */ if (srv_conn) { srv = objt_server(srv_conn->target); - si_idle_conn(&s->si[1], srv ? &srv->priv_conns : NULL); + if (!srv) + si_idle_conn(&s->si[1], NULL); + else if ((srv_conn->flags & CO_FL_PRIVATE) || + ((s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_NEVR)) + si_idle_conn(&s->si[1], &srv->priv_conns); + else + si_idle_conn(&s->si[1], &srv->idle_conns); } s->req.analysers = strm_li(s)->analysers;