diff --git a/include/types/proxy.h b/include/types/proxy.h index 9e6f42123..a82f195c2 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 2b3d70529..3800b4b5e 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 e55f20bba..2e2aaff47 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 145954385..d2b6d10ad 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 077335811..1c925968f 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 e87da3ec3..8ee2cf864 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 09770612e..4f1028900 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 d672fed00..8f0474cb8 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