[MEDIUM] split fe->maxconn into fe->maxconn and be->fullconn

The maxconn argument is used only for the listeners, and the
fullconn is used only for the backends. If unset, it inherits
maxconn's value which itself can inherit the default or the
global value (we might need to change this).
This commit is contained in:
Willy Tarreau 2006-12-29 00:10:33 +01:00
parent 97de624c17
commit 8603431822
3 changed files with 36 additions and 8 deletions

View File

@ -98,7 +98,8 @@ struct proxy {
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 int maxconn; /* max # of active sessions on the frontend */
unsigned int fullconn; /* #conns on backend above which servers are used at full load */
unsigned failed_conns, failed_resp; /* failed connect() and responses */
unsigned failed_secu; /* blocked responses because of security concerns */
int conn_retries; /* maximum number of connect retries */

View File

@ -395,6 +395,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
/* set default values */
curproxy->state = defproxy.state;
curproxy->maxconn = defproxy.maxconn;
curproxy->fullconn = defproxy.fullconn;
curproxy->conn_retries = defproxy.conn_retries;
curproxy->options = defproxy.options;
@ -909,6 +910,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
}
curproxy->maxconn = atol(args[1]);
}
else if (!strcmp(args[0], "fullconn")) { /* fullconn */
if (*(args[1]) == 0) {
Alert("parsing [%s:%d] : '%s' expects an integer argument.\n", file, linenum, args[0]);
return -1;
}
curproxy->fullconn = atol(args[1]);
}
else if (!strcmp(args[0], "grace")) { /* grace time (ms) */
if (*(args[1]) == 0) {
Alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
@ -1973,6 +1981,13 @@ int readcfgfile(const char *file)
memcpy(curproxy->check_req, sslv3_client_hello_pkt, sizeof(sslv3_client_hello_pkt));
}
/* for backwards compatibility with "listen" instances, if
* fullconn is not set but maxconn is set, then maxconn
* is used.
*/
if (!curproxy->fullconn)
curproxy->fullconn = curproxy->maxconn;
/* first, we will invert the servers list order */
newsrv = NULL;
while (curproxy->srv) {
@ -2035,13 +2050,18 @@ int readcfgfile(const char *file)
*/
newsrv = curproxy->srv;
while (newsrv != NULL) {
if (newsrv->minconn >= newsrv->maxconn) {
if (newsrv->minconn > newsrv->maxconn) {
/* Only 'minconn' was specified, or it was higher than or equal
* to 'maxconn'. Let's turn this into maxconn and clean it, as
* this will avoid further useless expensive computations.
*/
newsrv->maxconn = newsrv->minconn;
newsrv->minconn = 0;
} else if (newsrv->maxconn && !newsrv->minconn) {
/* minconn was not specified, so we set it to maxconn */
newsrv->minconn = newsrv->maxconn;
} else if (!curproxy->fullconn) {
Alert("parsing [%s:%d] : fullconn is mandatory when minconn is set on a server.\n", file, linenum);
return -1;
}
if (newsrv->maxconn > 0) {

View File

@ -25,14 +25,21 @@
void **pool_pendconn = NULL;
/* returns the effective dynamic maxconn for a server, considering the minconn
* and the proxy's usage relative to its saturation.
* and the proxy's usage relative to its dynamic connections limit. It is
* expected that 0 < s->minconn <= s->maxconn when this is called.
*/
unsigned int srv_dynamic_maxconn(const struct server *s)
{
return (s->proxy->beconn >= s->proxy->maxconn) ? s->maxconn :
(s->minconn ?
MAX(s->maxconn * s->proxy->beconn / s->proxy->maxconn, s->minconn)
: s->maxconn);
if (s->proxy->beconn >= s->proxy->fullconn)
/* no fullconn or proxy is full */
return s->maxconn;
if (s->minconn == s->maxconn)
/* static limit */
return s->maxconn;
return MAX(s->minconn,
s->proxy->beconn * s->maxconn / s->proxy->fullconn);
}