are not sized to accept such loads, and for this reason it is generally wise
to assign them some reasonable connection limits.
- By default, this value is set to 2000.
+ When this value is set to zero, which is the default, the global "maxconn"
+ value is used.
See also : "server", global section's "maxconn", "fullconn"
unsigned int buf_out, unsigned int err_pos,
const union error_snapshot_ctx *ctx,
void (*show)(struct buffer *, const struct error_snapshot *));
+void proxy_adjust_all_maxconn();
struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg);
struct proxy *cli_find_frontend(struct appctx *appctx, const char *arg);
char *cursection = NULL;
struct proxy defproxy = { }; /* fake proxy used to assign default values on all instances */
-int cfg_maxpconn = DEFAULT_MAXCONN; /* # of simultaneous connections per proxy (-N) */
+int cfg_maxpconn = 0; /* # of simultaneous connections per proxy (-N) */
int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
char *cfg_scope = NULL; /* the current scope during the configuration parsing */
} else {
free(curproxy->defbe.name);
curproxy->defbe.be = target;
- /* Update tot_fe_maxconn for a further fullconn's computation */
- target->tot_fe_maxconn += curproxy->maxconn;
/* Emit a warning if this proxy also has some servers */
if (curproxy->srv) {
ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
}
}
- if (!curproxy->defbe.be && (curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN) {
- /* Case of listen without default backend
- * The curproxy will be its own default backend
- * so we update tot_fe_maxconn for a further
- * fullconn's computation */
- curproxy->tot_fe_maxconn += curproxy->maxconn;
- }
-
/* find the target proxy for 'use_backend' rules */
list_for_each_entry(rule, &curproxy->switching_rules, list) {
struct proxy *target;
} else {
free((void *)rule->be.name);
rule->be.backend = target;
- /* For each target of switching rules, we update
- * their tot_fe_maxconn, except if a previous rule point
- * on the same backend or on the default backend */
- if (rule->be.backend != curproxy->defbe.be) {
- struct switching_rule *swrule;
-
- list_for_each_entry(swrule, &curproxy->switching_rules, list) {
- if (rule == swrule) {
- target->tot_fe_maxconn += curproxy->maxconn;
- break;
- }
- else if (!swrule->dynamic && swrule->be.backend == rule->be.backend) {
- /* there is multiple ref of this backend */
- break;
- }
- }
- }
}
}
}
}
- /* automatically compute fullconn if not set. We must not do it in the
- * loop above because cross-references are not yet fully resolved.
- */
- for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
- /* If <fullconn> is not set, let's set it to 10% of the sum of
- * the possible incoming frontend's maxconns.
- */
- if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
- /* we have the sum of the maxconns in <total>. We only
- * keep 10% of that sum to set the default fullconn, with
- * a hard minimum of 1 (to avoid a divide by zero).
- */
- curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
- if (!curproxy->fullconn)
- curproxy->fullconn = 1;
- }
- }
-
/*
* Recount currently required checks.
*/
global.maxsock += p->peers_fe->maxconn;
}
+ proxy_adjust_all_maxconn();
+
if (global.tune.maxpollevents <= 0)
global.tune.maxpollevents = MAX_POLL_EVENTS;
HA_SPIN_UNLOCK(PROXY_LOCK, &proxy->lock);
}
+/* Configure all proxies which lack a maxconn setting to use the global one by
+ * default. This avoids the common mistake consisting in setting maxconn only
+ * in the global section and discovering the hard way that it doesn't propagate
+ * through the frontends. These values are also propagated through the various
+ * targetted backends, whose fullconn is finally calculated if not yet set.
+ */
+void proxy_adjust_all_maxconn()
+{
+ struct proxy *curproxy;
+ struct switching_rule *swrule1, *swrule2;
+
+ for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
+ if (curproxy->state == PR_STSTOPPED)
+ continue;
+
+ if (!(curproxy->cap & PR_CAP_FE))
+ continue;
+
+ if (!curproxy->maxconn)
+ curproxy->maxconn = global.maxconn;
+
+ /* update the target backend's fullconn count : default_backend */
+ if (curproxy->defbe.be)
+ curproxy->defbe.be->tot_fe_maxconn += curproxy->maxconn;
+ else if ((curproxy->cap & PR_CAP_LISTEN) == PR_CAP_LISTEN)
+ curproxy->tot_fe_maxconn += curproxy->maxconn;
+
+ list_for_each_entry(swrule1, &curproxy->switching_rules, list) {
+ /* For each target of switching rules, we update their
+ * tot_fe_maxconn, except if a previous rule points to
+ * the same backend or to the default backend.
+ */
+ if (swrule1->be.backend != curproxy->defbe.be) {
+ list_for_each_entry(swrule2, &curproxy->switching_rules, list) {
+ if (swrule2 == swrule1) {
+ swrule1->be.backend->tot_fe_maxconn += curproxy->maxconn;
+ break;
+ }
+ else if (!swrule2->dynamic && swrule2->be.backend == swrule1->be.backend) {
+ /* there are multiple refs of this backend */
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* automatically compute fullconn if not set. We must not do it in the
+ * loop above because cross-references are not yet fully resolved.
+ */
+ for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
+ if (curproxy->state == PR_STSTOPPED)
+ continue;
+
+ /* If <fullconn> is not set, let's set it to 10% of the sum of
+ * the possible incoming frontend's maxconns.
+ */
+ if (!curproxy->fullconn && (curproxy->cap & PR_CAP_BE)) {
+ /* we have the sum of the maxconns in <total>. We only
+ * keep 10% of that sum to set the default fullconn, with
+ * a hard minimum of 1 (to avoid a divide by zero).
+ */
+ curproxy->fullconn = (curproxy->tot_fe_maxconn + 9) / 10;
+ if (!curproxy->fullconn)
+ curproxy->fullconn = 1;
+ }
+ }
+}
+
/* Config keywords below */
static struct cfg_kw_list cfg_kws = {ILH, {