From: Willy Tarreau Date: Sun, 17 Dec 2006 21:14:12 +0000 (+0100) Subject: [MEDIUM] separated nbconn into feconn and beconn X-Git-Tag: v1.3.4~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f1221aa19ff64d0702df0fa1af0808cfa019e435;p=thirdparty%2Fhaproxy.git [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. --- diff --git a/include/types/proxy.h b/include/types/proxy.h index 9e6f421237..a82f195c2a 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -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 */ diff --git a/include/types/session.h b/include/types/session.h index 2b3d705298..3800b4b5ee 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -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 */ diff --git a/src/client.c b/src/client.c index e55f20bbaa..2e2aaff474 100644 --- a/src/client.c +++ b/src/client.c @@ -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; } diff --git a/src/haproxy.c b/src/haproxy.c index 1459543850..d2b6d10ade 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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); diff --git a/src/log.c b/src/log.c index 077335811d..1c925968f5 100644 --- a/src/log.c +++ b/src/log.c @@ -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); } diff --git a/src/proto_http.c b/src/proto_http.c index e87da3ec32..8ee2cf8641 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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, "

> Proxy instance %s : " - "%d conns (maxconn=%d), %d queued (%d unassigned), %d total conns

\n" + "%d front conns (max=%d), %d back, " + "%d queued (%d unassigned), %d total front conns, %d back\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, "\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, - "", - dispatch_sess, px->nbconn_max, px->maxconn, dispatch_cum); + "", + 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, - "", - px->nbconn, px->nbconn_max, px->maxconn, px->cum_conn); + "", + px->beconn, px->beconn_max, px->cum_beconn); /* errors : connect, response, security */ msglen += snprintf(trash + msglen, sizeof(trash) - msglen, diff --git a/src/proxy.c b/src/proxy.c index 09770612ed..4f1028900d 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -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; } diff --git a/src/queue.c b/src/queue.c index d672fed001..8f0474cb80 100644 --- a/src/queue.c +++ b/src/queue.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -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); }
%d%d%d%d%d%d-%d%d%d%d%d%d%d-%d