MINOR: http: add option prefer-last-server

When the load balancing algorithm in use is not deterministic, and a previous
request was sent to a server to which haproxy still holds a connection, it is
sometimes desirable that subsequent requests on a same session go to the same
server as much as possible. Note that this is different from persistence, as
we only indicate a preference which haproxy tries to apply without any form
of warranty. The real use is for keep-alive connections sent to servers. When
this option is used, haproxy will try to reuse the same connection that is
attached to the server instead of rebalancing to another server, causing a
close of the connection. This can make sense for static file servers. It does
not make much sense to use this in combination with hashing algorithms.
This commit is contained in:
Willy Tarreau 2013-12-15 18:58:25 +01:00
parent 34601a8f98
commit 9420b1271d
4 changed files with 44 additions and 5 deletions

View File

@ -3794,7 +3794,9 @@ no option http-keep-alive
If the client request has to go to another backend or another server due to
content switching or the load balancing algorithm, the idle connection will
immediately be closed and a new one re-opened.
immediately be closed and a new one re-opened. Option "prefer-last-server" is
available to try optimize server selection so that if the server currently
attached to an idle connection is usable, it will be used.
In general it is preferred to use "option http-server-close" with application
servers, and some static servers might benefit from "option http-keep-alive".
@ -3815,8 +3817,8 @@ no option http-keep-alive
in a specific instance by prepending the "no" keyword before it.
See also : "option forceclose", "option http-server-close",
"option httpclose", "option http-pretend-keepalive" and
"1.1. The HTTP transaction model".
"option prefer-last-server", "option http-pretend-keepalive",
"option httpclose", and "1.1. The HTTP transaction model".
option http-no-delay
@ -4428,6 +4430,30 @@ option pgsql-check [ user <username> ]
See also: "option httpchk"
option prefer-last-server
no option prefer-last-server
Allow multiple load balanced requests to remain on the same server
May be used in sections: defaults | frontend | listen | backend
yes | no | yes | yes
Arguments : none
When the load balancing algorithm in use is not deterministic, and a previous
request was sent to a server to which haproxy still holds a connection, it is
sometimes desirable that subsequent requests on a same session go to the same
server as much as possible. Note that this is different from persistence, as
we only indicate a preference which haproxy tries to apply without any form
of warranty. The real use is for keep-alive connections sent to servers. When
this option is used, haproxy will try to reuse the same connection that is
attached to the server instead of rebalancing to another server, causing a
close of the connection. This can make sense for static file servers. It does
not make much sense to use this in combination with hashing algorithms.
If this option has been enabled in a "defaults" section, it can be disabled
in a specific instance by prepending the "no" keyword before it.
See also: "option http-keep-alive"
option redispatch
no option redispatch
Enable or disable session redistribution in case of connection failure

View File

@ -76,7 +76,8 @@ enum pr_mode {
/* bits for proxy->options */
#define PR_O_REDISP 0x00000001 /* allow reconnection to dispatch in case of errors */
#define PR_O_TRANSP 0x00000002 /* transparent mode : use original DEST as dispatch */
/* unused: 0x04, 0x08, 0x10, 0x20 */
/* unused: 0x04, 0x08, 0x10 */
#define PR_O_PREF_LAST 0x00000020 /* prefer last server */
#define PR_O_DISPATCH 0x00000040 /* use dispatch mode */
#define PR_O_KEEPALIVE 0x00000080 /* follow keep-alive sessions */
#define PR_O_FWDFOR 0x00000100 /* conditionally insert x-forwarded-for with client address */

View File

@ -532,8 +532,19 @@ int assign_server(struct session *s)
srv = NULL;
s->target = NULL;
conn = objt_conn(s->req->cons->end);
if (s->be->lbprm.algo & BE_LB_KIND) {
if (conn && (s->be->options & PR_O_PREF_LAST) &&
objt_server(conn->target) && __objt_server(conn->target)->proxy == s->be &&
srv_is_usable(__objt_server(conn->target)->state, __objt_server(conn->target)->eweight)) {
/* This session was relying on a server in a previous request
* and the proxy has "option prefer-current-server" set, so
* let's try to reuse the same server.
*/
srv = __objt_server(conn->target);
s->target = &srv->obj_type;
}
else if (s->be->lbprm.algo & BE_LB_KIND) {
/* we must check if we have at least one server available */
if (!s->be->lbprm.tot_weight) {
err = SRV_STATUS_NOSRV;

View File

@ -134,6 +134,7 @@ static const struct cfg_opt cfg_opts[] =
{ "httpclose", PR_O_HTTP_CLOSE, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
{ "http-keep-alive", PR_O_KEEPALIVE, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
{ "http-server-close", PR_O_SERVER_CLO, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
{ "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
{ "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
{ "nolinger", PR_O_TCP_NOLING, PR_CAP_FE | PR_CAP_BE, 0, 0 },
{ "persist", PR_O_PERSIST, PR_CAP_BE, 0, 0 },