From: Willy Tarreau Date: Sat, 3 Oct 2009 10:56:50 +0000 (+0200) Subject: [MEDIUM] backend: introduce the "static-rr" LB algorithm X-Git-Tag: v1.4-dev4~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9757a38feb5ee1c689c9c0d9c1288069a9432461;p=thirdparty%2Fhaproxy.git [MEDIUM] backend: introduce the "static-rr" LB algorithm The "static-rr" is just the old round-robin algorithm. It is still in use when a hash algorithm is used and the data to hash is not present, but it was impossible to configure it explicitly. This one is cheaper in terms of CPU and supports unlimited numbers of servers, so it makes sense to be able to use it. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index c7e582df98..3b7648b3cf 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 a73a36a96a..a8f8586fce 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 14ae7055aa..39726cedff 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 de84f376c2..7bb94b8363 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;