[MINOR] acl: add new keyword "connslots"

I'm in the process of setting up one haproxy instance now, and I find
the following acl option useful. I'm not too sure why this option has
not been available before, but I find this useful for my own usage, so
I'm submitting this patch in the hope that it will be useful as well.

The basic idea is to be able to measure the available connection slots
still available (connection, + queue) - anything beyond that can be
redirected to a different backend. 'connslots' = number of available
server connection slots, + number of available server queue slots. In
the case where we encounter srv maxconn = 0, or srv maxqueue = 0 (in
which case we dont need to care about connslots) the value you get is
-1. Note also that this code does not take care of dynamic connections
at this point in time.

The reason why I'm using this new acl (as opposed to 'nbsrv') is that
'nbsrv' only measures servers that are actually *down*. Whereas this
other acl is more fine-grained, and looks into the number of conn
slots available as well.
This commit is contained in:
Jeffrey 'jf' Lim 2008-09-04 01:03:03 +08:00 committed by Willy Tarreau
parent 3dfe6cd095
commit 5051d7bffc
2 changed files with 59 additions and 1 deletions

View File

@ -3764,6 +3764,27 @@ nbsrv(backend) <integer>
to handle some load. It is useful to report a failure when combined with
"monitor fail".
connslots <integer>
connslots(backend) <integer>
The basic idea here is to be able to measure the number of connection "slots"
still available (connection, + queue) - so that anything beyond that (intended
usage; see "use_backend" keyword) can be redirected to a different backend.
'connslots' = number of available server connection slots, + number of available
server queue slots.
*Note that while "dst_conn" may be used, "connslots" comes in especially useful
when you have a case of traffic going to one single ip, splitting into multiple
backends (perhaps using acls to do name-based load balancing) - and you want to
be able to differentiate between different backends, and their "connslots"
available. Also, whereas "nbsrv" only measures servers that are actually *down*,
this acl is more fine-grained - and looks into the number of conn slots available
as well.
*OTHER CAVEATS AND NOTES: at this point in time, the code does not take care of
dynamic connections. Also, if any of the server maxconn, or maxqueue is 0, then
this acl clearly does not make sense - in which case the value returned will be -1.
2.3.5.2) Matching contents at Layer 4
-------------------------------------

View File

@ -2048,10 +2048,47 @@ acl_fetch_nbsrv(struct proxy *px, struct session *l4, void *l7, int dir,
return 1;
}
/* set test->i to the number of enabled servers on the proxy */
static int
acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
struct acl_expr *expr, struct acl_test *test)
{
struct server *iterator;
test->flags = ACL_TEST_F_VOL_TEST;
if (expr->arg_len) {
/* another proxy was designated, we must look for it */
for (px = proxy; px; px = px->next)
if ((px->cap & PR_CAP_BE) && !strcmp(px->id, expr->arg.str))
break;
}
if (!px)
return 0;
test->i = 0;
iterator = px->srv;
while (iterator) {
if ((iterator->state & 1) == 0) {
iterator = iterator->next;
continue;
}
if (iterator->maxconn == 0 || iterator->maxqueue == 0) {
test->i = -1;
return 1;
}
test->i += (iterator->maxconn - iterator->cur_sess)
+ (iterator->maxqueue - iterator->nbpend);
iterator = iterator->next;
}
return 1;
}
/* Note: must not be declared <const> as its list will be overwritten */
static struct acl_kw_list acl_kws = {{ },{
{ "nbsrv", acl_parse_int, acl_fetch_nbsrv, acl_match_int, ACL_USE_NOTHING },
{ "connlots", acl_parse_int, acl_fetch_connslots, acl_match_int, ACL_USE_NOTHING },
{ NULL, NULL, NULL, NULL },
}};