diff --git a/doc/configuration.txt b/doc/configuration.txt index c7e582df9..3b7648b3c 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -915,7 +915,23 @@ balance url_param [check_post []] This is the smoothest and fairest algorithm when the server's processing time remains equally distributed. This algorithm is dynamic, which means that server weights may be adjusted - on the fly for slow starts for instance. + on the fly for slow starts for instance. It is limited by + design to 4128 active servers per backend. Note that in some + large farms, when a server becomes up after having been down + for a very short time, it may sometimes take a few hundreds + requests for it to be re-integrated into the farm and start + receiving traffic. This is normal, though very rare. It is + indicated here in case you would have the chance to observe + it, so that you don't worry. + + static-rr Each server is used in turns, according to their weights. + This algorithm is as similar to roundrobin except that it is + static, which means that changing a server's weight on the + fly will have no effect. On the other hand, it has no design + limitation on the number of servers, and when a server goes + up, it is always immediately reintroduced into the farm, once + the full map is recomputed. It also uses slightly less CPU to + run (around -1%). leastconn The server with the lowest number of connections receives the connection. Round-robin is performed within groups of servers diff --git a/include/types/backend.h b/include/types/backend.h index a73a36a96..a8f8586fc 100644 --- a/include/types/backend.h +++ b/include/types/backend.h @@ -42,6 +42,9 @@ #define BE_LB_HASH_PRM 0x00002 /* hash HTTP URL parameter */ #define BE_LB_HASH_HDR 0x00003 /* hash HTTP header value */ #define BE_LB_HASH_RDP 0x00004 /* hash RDP cookie value */ + +#define BE_LB_RR_DYN 0x00000 /* dynamic round robin (default) */ +#define BE_LB_RR_STATIC 0x00001 /* static round robin */ #define BE_LB_PARM 0x000FF /* mask to get/clear the LB param */ /* Required input(s) */ @@ -65,6 +68,7 @@ #define BE_LB_ALGO_NONE (BE_LB_KIND_NONE | BE_LB_NEED_NONE) /* not defined */ #define BE_LB_ALGO_RR (BE_LB_KIND_RR | BE_LB_NEED_NONE) /* round robin */ #define BE_LB_ALGO_LC (BE_LB_KIND_LC | BE_LB_NEED_NONE) /* least connections */ +#define BE_LB_ALGO_SRR (BE_LB_KIND_RR | BE_LB_NEED_NONE | BE_LB_RR_STATIC) /* static round robin */ #define BE_LB_ALGO_SH (BE_LB_KIND_HI | BE_LB_NEED_ADDR | BE_LB_HASH_SRC) /* hash: source IP */ #define BE_LB_ALGO_UH (BE_LB_KIND_HI | BE_LB_NEED_HTTP | BE_LB_HASH_URI) /* hash: HTTP URI */ #define BE_LB_ALGO_PH (BE_LB_KIND_HI | BE_LB_NEED_HTTP | BE_LB_HASH_PRM) /* hash: HTTP URL parameter */ diff --git a/src/backend.c b/src/backend.c index 14ae7055a..39726cedf 100644 --- a/src/backend.c +++ b/src/backend.c @@ -516,7 +516,11 @@ int assign_server(struct session *s) break; case BE_LB_LKUP_MAP: - if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI) { + if ((s->be->lbprm.algo & BE_LB_KIND) == BE_LB_KIND_RR) { + s->srv = map_get_server_rr(s->be, s->prev_srv); + break; + } + else if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI) { /* unknown balancing algorithm */ err = SRV_STATUS_INTERNAL; goto out; @@ -973,6 +977,10 @@ int backend_parse_balance(const char **args, char *err, int errlen, struct proxy curproxy->lbprm.algo &= ~BE_LB_ALGO; curproxy->lbprm.algo |= BE_LB_ALGO_RR; } + else if (!strcmp(args[0], "static-rr")) { + curproxy->lbprm.algo &= ~BE_LB_ALGO; + curproxy->lbprm.algo |= BE_LB_ALGO_SRR; + } else if (!strcmp(args[0], "leastconn")) { curproxy->lbprm.algo &= ~BE_LB_ALGO; curproxy->lbprm.algo |= BE_LB_ALGO_LC; @@ -1098,7 +1106,7 @@ int backend_parse_balance(const char **args, char *err, int errlen, struct proxy } } else { - snprintf(err, errlen, "'balance' only supports 'roundrobin', 'leastconn', 'source', 'uri', 'url_param', 'hdr(name)' and 'rdp-cookie(name)' options."); + snprintf(err, errlen, "'balance' only supports 'roundrobin', 'static-rr', 'leastconn', 'source', 'uri', 'url_param', 'hdr(name)' and 'rdp-cookie(name)' options."); return -1; } return 0; diff --git a/src/cfgparse.c b/src/cfgparse.c index de84f376c..7bb94b836 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -4196,8 +4196,13 @@ int check_config_validity() curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN); switch (curproxy->lbprm.algo & BE_LB_KIND) { case BE_LB_KIND_RR: - curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN; - fwrr_init_server_groups(curproxy); + if ((curproxy->lbprm.algo & BE_LB_PARM) == BE_LB_RR_STATIC) { + curproxy->lbprm.algo |= BE_LB_LKUP_MAP; + init_server_map(curproxy); + } else { + curproxy->lbprm.algo |= BE_LB_LKUP_RRTREE | BE_LB_PROP_DYN; + fwrr_init_server_groups(curproxy); + } break; case BE_LB_KIND_LC: curproxy->lbprm.algo |= BE_LB_LKUP_LCTREE | BE_LB_PROP_DYN;