mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-25 04:17:42 +00:00
[MINOR] acl: add fe_conn, be_conn, queue, avg_queue
These ACLs are used to check the number of active connections on the frontend, backend or in a backend's queue. The avg_queue returns the average number of queued connections per server, and for this, divides the total number of queued connections by the number of alive servers. The dst_conn ACL has been slightly changed to more reflect its name and original usage, which is to return the number of connections on the destination address/port (the socket) and not the whole frontend.
This commit is contained in:
parent
6b2e11be1e
commit
a36af91951
@ -5041,10 +5041,30 @@ dst_port <integer>
|
||||
to a different backend for some alternative ports.
|
||||
|
||||
dst_conn <integer>
|
||||
Applies to the number of currently established connections on the frontend,
|
||||
Applies to the number of currently established connections on the same socket
|
||||
including the one being evaluated. It can be used to either return a sorry
|
||||
page before hard-blocking, or to use a specific backend to drain new requests
|
||||
when the farm is considered saturated.
|
||||
when the socket is considered saturated. This offers the ability to assign
|
||||
different limits to different listening ports or addresses. See also the
|
||||
"fe_conn" and "be_conn" criteria.
|
||||
|
||||
fe_conn <integer>
|
||||
fe_conn(frontend) <integer>
|
||||
Applies to the number of currently established connections on the frontend,
|
||||
possibly including the connection being evaluated. If no frontend name is
|
||||
specified, the current one is used. But it is also possible to check another
|
||||
frontend. It can be used to either return a sorry page before hard-blocking,
|
||||
or to use a specific backend to drain new requests when the farm is
|
||||
considered saturated. See also the "dst_conn", "be_conn" and "fe_sess_rate"
|
||||
criteria.
|
||||
|
||||
be_conn <integer>
|
||||
be_conn(frontend) <integer>
|
||||
Applies to the number of currently established connections on the backend,
|
||||
possibly including the connection being evaluated. If no backend name is
|
||||
specified, the current one is used. But it is also possible to check another
|
||||
backend. It can be used to use a specific farm when the nominal one is full.
|
||||
See also the "fe_conn", "queue" and "be_sess_rate" criteria.
|
||||
|
||||
nbsrv <integer>
|
||||
nbsrv(backend) <integer>
|
||||
@ -5063,19 +5083,43 @@ connslots(backend) <integer>
|
||||
'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
|
||||
Note that while "fe_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
|
||||
available "connslots". Also, whereas "nbsrv" only measures servers that are
|
||||
actually *down*, this acl is more fine-grained and looks into the number of
|
||||
available connection slots as well.
|
||||
available connection slots as well. See also "queue" and "avg_queue".
|
||||
|
||||
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.
|
||||
|
||||
queue <integer>
|
||||
queue(frontend) <integer>
|
||||
Returns the total number of queued connections of the designated backend,
|
||||
including all the connections in server queues. If no backend name is
|
||||
specified, the current one is used, but it is also possible to check another
|
||||
one. This can be used to take actions when queuing goes above a known level,
|
||||
generally indicating a surge of traffic or a massive slowdown on the servers.
|
||||
One possible action could be to reject new users but still accept old ones.
|
||||
See also the "avg_queue", "be_conn", and "be_sess_rate" criteria.
|
||||
|
||||
avg_queue <integer>
|
||||
avg_queue(frontend) <integer>
|
||||
Returns the total number of queued connections of the designated backend
|
||||
divided by the number of active servers. This is very similar to "queue"
|
||||
except that the size of the farm is considered, in order to give a more
|
||||
accurate measurement of the time it may take for a new connection to be
|
||||
processed. The main usage is to return a sorry page to new users when it
|
||||
becomes certain they will get a degraded service. Note that in the event
|
||||
there would not be any active server anymore, we would consider twice the
|
||||
number of queued connections as the measured value. This is a fair estimate,
|
||||
as we expect one server to get back soon anyway, but we still prefer to send
|
||||
new traffic to another backend if in better shape. See also the "queue",
|
||||
"be_conn", and "be_sess_rate" criteria.
|
||||
|
||||
fe_sess_rate <integer>
|
||||
fe_sess_rate(frontend) <integer>
|
||||
Returns true when the session creation rate on the current or the named
|
||||
|
@ -1188,7 +1188,7 @@ acl_fetch_connslots(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
test->i = 0;
|
||||
iterator = px->srv;
|
||||
while (iterator) {
|
||||
if ((iterator->state & 1) == 0) {
|
||||
if ((iterator->state & SRV_RUNNING) == 0) {
|
||||
iterator = iterator->next;
|
||||
continue;
|
||||
}
|
||||
@ -1243,6 +1243,99 @@ acl_fetch_be_sess_rate(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set test->i to the number of concurrent connections on the frontend */
|
||||
static int
|
||||
acl_fetch_fe_conn(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
struct acl_expr *expr, struct acl_test *test)
|
||||
{
|
||||
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_FE) && !strcmp(px->id, expr->arg.str))
|
||||
break;
|
||||
}
|
||||
if (!px)
|
||||
return 0;
|
||||
|
||||
test->i = px->feconn;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set test->i to the number of concurrent connections on the backend */
|
||||
static int
|
||||
acl_fetch_be_conn(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
struct acl_expr *expr, struct acl_test *test)
|
||||
{
|
||||
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 = px->beconn;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set test->i to the total number of queued connections on the backend */
|
||||
static int
|
||||
acl_fetch_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
struct acl_expr *expr, struct acl_test *test)
|
||||
{
|
||||
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 = px->totpend;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set test->i to the total number of queued connections on the backend divided
|
||||
* by the number of running servers and rounded up. If there is no running
|
||||
* server, we return twice the total, just as if we had half a running server.
|
||||
* This is more or less correct anyway, since we expect the last server to come
|
||||
* back soon.
|
||||
*/
|
||||
static int
|
||||
acl_fetch_avg_queue_size(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
struct acl_expr *expr, struct acl_test *test)
|
||||
{
|
||||
int nbsrv;
|
||||
|
||||
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;
|
||||
|
||||
if (px->srv_act)
|
||||
nbsrv = px->srv_act;
|
||||
else if (px->lbprm.fbck)
|
||||
nbsrv = 1;
|
||||
else
|
||||
nbsrv = px->srv_bck;
|
||||
|
||||
if (nbsrv > 0)
|
||||
test->i = (px->totpend + nbsrv - 1) / nbsrv;
|
||||
else
|
||||
test->i = px->totpend * 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
@ -1250,6 +1343,10 @@ static struct acl_kw_list acl_kws = {{ },{
|
||||
{ "connslots", acl_parse_int, acl_fetch_connslots, acl_match_int, ACL_USE_NOTHING },
|
||||
{ "fe_sess_rate", acl_parse_int, acl_fetch_fe_sess_rate, acl_match_int, ACL_USE_NOTHING },
|
||||
{ "be_sess_rate", acl_parse_int, acl_fetch_be_sess_rate, acl_match_int, ACL_USE_NOTHING },
|
||||
{ "fe_conn", acl_parse_int, acl_fetch_fe_conn, acl_match_int, ACL_USE_NOTHING },
|
||||
{ "be_conn", acl_parse_int, acl_fetch_be_conn, acl_match_int, ACL_USE_NOTHING },
|
||||
{ "queue", acl_parse_int, acl_fetch_queue_size, acl_match_int, ACL_USE_NOTHING },
|
||||
{ "avg_queue", acl_parse_int, acl_fetch_avg_queue_size, acl_match_int, ACL_USE_NOTHING },
|
||||
{ NULL, NULL, NULL, NULL },
|
||||
}};
|
||||
|
||||
|
@ -593,12 +593,12 @@ acl_fetch_dport(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
}
|
||||
|
||||
|
||||
/* set test->i to the number of connexions to the proxy */
|
||||
/* set test->i to the number of connexions to the same listening socket */
|
||||
static int
|
||||
acl_fetch_dconn(struct proxy *px, struct session *l4, void *l7, int dir,
|
||||
struct acl_expr *expr, struct acl_test *test)
|
||||
{
|
||||
test->i = px->feconn;
|
||||
test->i = l4->listener->nbconn;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user