[MEDIUM] separated nbconn into feconn and beconn

The nbconn attribute in the proxies was not relevant anymore because
a frontend A may use backend B and both of them must account for their
respective connections. For this reason, there now are two separate
counters for frontend and backend connections.

The stats page has been updated to reflect the backend, but a separate
line entry for the frontend with error counts would be good.

Note that as of now, beconn may be higher than maxconn, because maxconn
applies to the frontend, while beconn may be increased due to sessions
passed from another frontend.
This commit is contained in:
Willy Tarreau 2006-12-17 22:14:12 +01:00
parent 830ff458de
commit f1221aa19f
8 changed files with 61 additions and 29 deletions

View File

@ -94,8 +94,9 @@ struct proxy {
struct list pendconns; /* pending connections with no server assigned yet */
int nbpend, nbpend_max; /* number of pending connections with no server assigned yet */
int totpend; /* total number of pending connections on this instance (for stats) */
unsigned int nbconn, nbconn_max; /* # of active sessions */
unsigned int cum_conn; /* cumulated number of processed sessions */
unsigned int feconn, feconn_max; /* # of active frontend sessions */
unsigned int beconn, beconn_max; /* # of active backend sessions */
unsigned int cum_feconn, cum_beconn; /* cumulated number of processed sessions */
unsigned int maxconn; /* max # of active sessions */
unsigned failed_conns, failed_resp; /* failed connect() and responses */
unsigned failed_secu; /* blocked responses because of security concerns */

View File

@ -45,7 +45,7 @@
#define SN_CLALLOW 0x00000004 /* a client header matches an allow regex */
#define SN_SVDENY 0x00000008 /* a server header matches a deny regex */
#define SN_SVALLOW 0x00000010 /* a server header matches an allow regex */
#define SN_UNUSED_1 0x00000020 /* unused bit */
#define SN_BE_ASSIGNED 0x00000020 /* a backend was assigned. Conns are accounted. */
/* session flags dedicated to cookies : bits values 0x40, 0x80 (0-3 shift 6) */
#define SN_CK_NONE 0x00000000 /* this session had no cookie */

View File

@ -65,7 +65,7 @@ int event_accept(int fd) {
else
max_accept = -1;
while (p->nbconn < p->maxconn && max_accept--) {
while (p->feconn < p->maxconn && max_accept--) {
struct sockaddr_storage addr;
socklen_t laddr = sizeof(addr);
@ -191,7 +191,7 @@ int event_accept(int fd) {
s->data_source = DATA_SRC_NONE;
s->uniq_id = totalconn;
p->cum_conn++;
p->cum_feconn++; /* cum_beconn will be increased once assigned */
s->rsp_cap = NULL;
s->hreq.cap = NULL;
@ -415,14 +415,14 @@ int event_accept(int fd) {
if (p->mode != PR_MODE_HEALTH)
task_wakeup(&rq, t);
p->nbconn++;
if (p->nbconn > p->nbconn_max)
p->nbconn_max = p->nbconn;
p->feconn++; /* beconn will be increased later */
if (p->feconn > p->feconn_max)
p->feconn_max = p->feconn;
actconn++;
totalconn++;
// fprintf(stderr, "accepting from %p => %d conn, %d total, task=%p\n", p, actconn, totalconn, t);
} /* end of while (p->nbconn < p->maxconn) */
} /* end of while (p->feconn < p->maxconn) */
return 0;
}

View File

@ -233,16 +233,16 @@ void sig_dump_state(int sig)
if (p->srv_act == 0) {
snprintf(trash, sizeof(trash),
"SIGHUP: Proxy %s %s ! Conn: %d act, %d pend (%d unass), %d tot.",
"SIGHUP: Proxy %s %s ! Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %d+%d.",
p->id,
(p->srv_bck) ? "is running on backup servers" : "has no server available",
p->nbconn, p->totpend, p->nbpend, p->cum_conn);
p->feconn, p->beconn, p->totpend, p->nbpend, p->cum_feconn, p->cum_beconn);
} else {
snprintf(trash, sizeof(trash),
"SIGHUP: Proxy %s has %d active servers and %d backup servers available."
" Conn: %d act, %d pend (%d unass), %d tot.",
" Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %d+%d.",
p->id, p->srv_act, p->srv_bck,
p->nbconn, p->totpend, p->nbpend, p->cum_conn);
p->feconn, p->beconn, p->totpend, p->nbpend, p->cum_feconn, p->cum_beconn);
}
Warning("%s\n", trash);
send_log(p, LOG_NOTICE, "%s\n", trash);

View File

@ -386,7 +386,7 @@ void sess_log(struct session *s)
sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT],
(p->options & PR_O_COOK_ANY) ? sess_cookie[(s->flags & SN_CK_MASK) >> SN_CK_SHIFT] : '-',
(p->options & PR_O_COOK_ANY) ? sess_set_cookie[(s->flags & SN_SCK_MASK) >> SN_SCK_SHIFT] : '-',
s->srv ? s->srv->cur_sess : 0, p->nbconn, actconn,
s->srv ? s->srv->cur_sess : 0, p->beconn, actconn,
s->logs.srv_queue_size, s->logs.prx_queue_size, tmpline);
}
else {
@ -406,7 +406,7 @@ void sess_log(struct session *s)
(p->to_log & LW_BYTES) ? "" : "+", s->logs.bytes,
sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT],
sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT],
s->srv ? s->srv->cur_sess : 0, p->nbconn, actconn,
s->srv ? s->srv->cur_sess : 0, p->beconn, actconn,
s->logs.srv_queue_size, s->logs.prx_queue_size);
}

View File

@ -258,7 +258,9 @@ int process_session(struct task *t)
return tv_remain2(&now, &t->expire); /* nothing more to do */
}
s->fe->nbconn--;
s->fe->feconn--;
if (s->flags & SN_BE_ASSIGNED)
s->be->beprm->beconn--;
actconn--;
if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) {
@ -917,6 +919,18 @@ int process_cli(struct session *t)
t->hreq.meth = find_http_meth(t->hreq.start.str, t->hreq.start.len);
}
if (!(t->flags & SN_BE_ASSIGNED) && (t->be != cur_proxy)) {
/* to ensure correct connection accounting on
* the backend, we count the connection for the
* one managing the queue.
*/
t->be->beprm->beconn++;
if (t->be->beprm->beconn > t->be->beprm->beconn_max)
t->be->beprm->beconn_max = t->be->beprm->beconn;
t->be->beprm->cum_beconn++;
t->flags |= SN_BE_ASSIGNED;
}
/* has the request been denied ? */
if (t->flags & SN_CLDENY) {
/* no need to go further */
@ -949,6 +963,19 @@ int process_cli(struct session *t)
} while (cur_proxy != t->be); /* we loop only if t->be has changed */
if (!(t->flags & SN_BE_ASSIGNED)) {
/* To ensure correct connection accounting on
* the backend, we count the connection for the
* one managing the queue.
*/
t->be->beprm->beconn++;
if (t->be->beprm->beconn > t->be->beprm->beconn_max)
t->be->beprm->beconn_max = t->be->beprm->beconn;
t->be->beprm->cum_beconn++;
t->flags |= SN_BE_ASSIGNED;
}
/*
* Right now, we know that we have processed the entire headers
* and that unwanted requests have been filtered out. We can do
@ -2748,10 +2775,12 @@ int produce_content(struct session *s)
msglen += snprintf(trash + msglen, sizeof(trash) - msglen,
"<h3>&gt; Proxy instance %s : "
"%d conns (maxconn=%d), %d queued (%d unassigned), %d total conns</h3>\n"
"%d front conns (max=%d), %d back, "
"%d queued (%d unassigned), %d total front conns, %d back</h3>\n"
"",
px->id,
px->nbconn, px->maxconn, px->totpend, px->nbpend, px->cum_conn);
px->feconn, px->maxconn, px->beconn,
px->totpend, px->nbpend, px->cum_feconn, px->cum_beconn);
msglen += snprintf(trash + msglen, sizeof(trash) - msglen,
"<table cols=\"16\" class=\"tbl\">\n"
@ -2853,8 +2882,8 @@ int produce_content(struct session *s)
* failed. We cannot count this during the servers dump because it
* might be interrupted multiple times.
*/
dispatch_sess = px->nbconn;
dispatch_cum = px->cum_conn;
dispatch_sess = px->beconn;
dispatch_cum = px->cum_beconn;
failed_secu = px->failed_secu;
failed_conns = px->failed_conns;
failed_resp = px->failed_resp;
@ -2888,8 +2917,8 @@ int produce_content(struct session *s)
/* sessions : current, max, limit, cumul. */
msglen += snprintf(trash + msglen, sizeof(trash) - msglen,
"<td align=right>%d</td><td align=right>%d</td><td align=right>%d</td><td align=right>%d</td>",
dispatch_sess, px->nbconn_max, px->maxconn, dispatch_cum);
"<td align=right>%d</td><td align=right>%d</td><td align=right>-</td><td align=right>%d</td>",
dispatch_sess, px->beconn_max, dispatch_cum);
/* errors : connect, response, security */
msglen += snprintf(trash + msglen, sizeof(trash) - msglen,
@ -2917,8 +2946,8 @@ int produce_content(struct session *s)
/* sessions : current, max, limit, cumul */
msglen += snprintf(trash + msglen, sizeof(trash) - msglen,
"<td align=right><b>%d</b></td><td align=right><b>%d</b></td><td align=right><b>%d</b></td><td align=right><b>%d</b></td>",
px->nbconn, px->nbconn_max, px->maxconn, px->cum_conn);
"<td align=right><b>%d</b></td><td align=right><b>%d</b></td><td align=right><b>-</b></td><td align=right><b>%d</b></td>",
px->beconn, px->beconn_max, px->cum_beconn);
/* errors : connect, response, security */
msglen += snprintf(trash + msglen, sizeof(trash) - msglen,

View File

@ -161,7 +161,7 @@ int maintain_proxies(void)
/* if there are enough free sessions, we'll activate proxies */
if (actconn < global.maxconn) {
while (p) {
if (p->nbconn < p->maxconn) {
if (p->feconn < p->maxconn) {
if (p->state == PR_STIDLE) {
for (l = p->listen; l != NULL; l = l->next) {
MY_FD_SET(l->fd, StaticReadEvent);
@ -322,7 +322,7 @@ void listen_proxies(void)
for (l = p->listen; l != NULL; l = l->next) {
if (listen(l->fd, p->maxconn) == 0) {
if (actconn < global.maxconn && p->nbconn < p->maxconn) {
if (actconn < global.maxconn && p->feconn < p->maxconn) {
MY_FD_SET(l->fd, StaticReadEvent);
p->state = PR_STRUN;
}

View File

@ -12,6 +12,7 @@
#include <common/config.h>
#include <common/time.h>
#include <common/tools.h>
#include <types/proxy.h>
#include <types/session.h>
@ -28,9 +29,10 @@ void **pool_pendconn = NULL;
*/
unsigned int srv_dynamic_maxconn(const struct server *s)
{
return s->minconn ?
((s->maxconn * s->proxy->nbconn / s->proxy->maxconn) < s->minconn) ? s->minconn :
(s->maxconn * s->proxy->nbconn / s->proxy->maxconn) : s->maxconn;
return (s->proxy->beconn >= s->proxy->maxconn) ? s->maxconn :
(s->minconn ?
MAX(s->maxconn * s->proxy->beconn / s->proxy->maxconn, s->minconn)
: s->maxconn);
}