mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-24 23:31:40 +02:00
[MINOR] add a weight divisor to the struct proxy
Under some circumstances, it will be useful to be able to have a server's effective weight bigger than the user weight, and this is particularly true for dynamic weight-based algorithms. In order to support this, we add a "wdiv" member to the lbprm structure which will always be used to divide the weights before reporting them.
This commit is contained in:
parent
2069704492
commit
5dc2fa660c
@ -42,6 +42,7 @@ int backend_parse_balance(const char **args, char *err,
|
||||
void recount_servers(struct proxy *px);
|
||||
void recalc_server_map(struct proxy *px);
|
||||
int be_downtime(struct proxy *px);
|
||||
void init_server_map(struct proxy *p);
|
||||
|
||||
/*
|
||||
* This function tries to find a running server with free connection slots for
|
||||
|
@ -86,6 +86,7 @@ struct proxy {
|
||||
int tot_weight; /* total effective weight of servers participating to LB */
|
||||
int tot_used; /* total number of servers used for LB */
|
||||
int wmult; /* ratio between user weight and effective weight */
|
||||
int wdiv; /* ratio between effective weight and user weight */
|
||||
struct {
|
||||
struct server **srv; /* the server map used to apply weights */
|
||||
int rr_idx; /* next server to be elected in round robin mode */
|
||||
|
@ -161,6 +161,59 @@ void recalc_server_map(struct proxy *px)
|
||||
px->lbprm.map.state &= ~PR_MAP_RECALC;
|
||||
}
|
||||
|
||||
/* This function is responsible of building the server MAP for map-based LB
|
||||
* algorithms, allocating the map, and setting p->lbprm.wmult to the GCD of the
|
||||
* weights if applicable. It should be called only once per proxy, at config
|
||||
* time.
|
||||
*/
|
||||
void init_server_map(struct proxy *p)
|
||||
{
|
||||
struct server *srv;
|
||||
int pgcd;
|
||||
int act, bck;
|
||||
|
||||
if (!p->srv)
|
||||
return;
|
||||
|
||||
/* We will factor the weights to reduce the table,
|
||||
* using Euclide's largest common divisor algorithm
|
||||
*/
|
||||
pgcd = p->srv->uweight;
|
||||
for (srv = p->srv->next; srv && pgcd > 1; srv = srv->next) {
|
||||
int w = srv->uweight;
|
||||
while (w) {
|
||||
int t = pgcd % w;
|
||||
pgcd = w;
|
||||
w = t;
|
||||
}
|
||||
}
|
||||
|
||||
/* It is sometimes useful to know what factor to apply
|
||||
* to the backend's effective weight to know its real
|
||||
* weight.
|
||||
*/
|
||||
p->lbprm.wmult = pgcd;
|
||||
|
||||
act = bck = 0;
|
||||
for (srv = p->srv; srv; srv = srv->next) {
|
||||
srv->eweight = srv->uweight / pgcd;
|
||||
if (srv->state & SRV_BACKUP)
|
||||
bck += srv->eweight;
|
||||
else
|
||||
act += srv->eweight;
|
||||
}
|
||||
|
||||
/* this is the largest map we will ever need for this servers list */
|
||||
if (act < bck)
|
||||
act = bck;
|
||||
|
||||
p->lbprm.map.srv = (struct server **)calloc(act, sizeof(struct server *));
|
||||
/* recounts servers and their weights */
|
||||
p->lbprm.map.state = PR_MAP_RECALC;
|
||||
recount_servers(p);
|
||||
recalc_server_map(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function tries to find a running server for the proxy <px> following
|
||||
* the URL parameter hash method. It looks for a specific parameter in the
|
||||
|
@ -2653,53 +2653,9 @@ int readcfgfile(const char *file)
|
||||
}
|
||||
|
||||
curproxy->lbprm.wmult = 1; /* default weight multiplier */
|
||||
curproxy->lbprm.wdiv = 1; /* default weight divider */
|
||||
|
||||
/* now, newsrv == curproxy->srv */
|
||||
if (newsrv) {
|
||||
struct server *srv;
|
||||
int pgcd;
|
||||
int act, bck;
|
||||
|
||||
/* We will factor the weights to reduce the table,
|
||||
* using Euclide's largest common divisor algorithm
|
||||
*/
|
||||
pgcd = newsrv->uweight;
|
||||
for (srv = newsrv->next; srv && pgcd > 1; srv = srv->next) {
|
||||
int t, w;
|
||||
|
||||
w = srv->uweight;
|
||||
while (w) {
|
||||
t = pgcd % w;
|
||||
pgcd = w;
|
||||
w = t;
|
||||
}
|
||||
}
|
||||
|
||||
/* It is sometimes useful to know what factor to apply
|
||||
* to the backend's effective weight to know its real
|
||||
* weight.
|
||||
*/
|
||||
curproxy->lbprm.wmult = pgcd;
|
||||
|
||||
act = bck = 0;
|
||||
for (srv = newsrv; srv; srv = srv->next) {
|
||||
srv->eweight = srv->uweight / pgcd;
|
||||
if (srv->state & SRV_BACKUP)
|
||||
bck += srv->eweight;
|
||||
else
|
||||
act += srv->eweight;
|
||||
}
|
||||
|
||||
/* this is the largest map we will ever need for this servers list */
|
||||
if (act < bck)
|
||||
act = bck;
|
||||
|
||||
curproxy->lbprm.map.srv = (struct server **)calloc(act, sizeof(struct server *));
|
||||
/* recounts servers and their weights */
|
||||
curproxy->lbprm.map.state = PR_MAP_RECALC;
|
||||
recount_servers(curproxy);
|
||||
recalc_server_map(curproxy);
|
||||
}
|
||||
init_server_map(curproxy);
|
||||
|
||||
if (curproxy->options & PR_O_LOGASAP)
|
||||
curproxy->to_log &= ~LW_BYTES;
|
||||
|
@ -756,7 +756,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri,
|
||||
/* act, bck */
|
||||
"<td>%s</td><td>%s</td>"
|
||||
"",
|
||||
sv->uweight,
|
||||
sv->eweight * px->lbprm.wmult / px->lbprm.wdiv,
|
||||
(sv->state & SRV_BACKUP) ? "-" : "Y",
|
||||
(sv->state & SRV_BACKUP) ? "Y" : "-");
|
||||
|
||||
@ -808,7 +808,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri,
|
||||
/* weight, active, backup */
|
||||
"%d,%d,%d,"
|
||||
"",
|
||||
sv->uweight,
|
||||
sv->eweight * px->lbprm.wmult / px->lbprm.wdiv,
|
||||
(sv->state & SRV_BACKUP) ? 0 : 1,
|
||||
(sv->state & SRV_BACKUP) ? 1 : 0);
|
||||
|
||||
@ -872,7 +872,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri,
|
||||
px->retries, px->redispatches,
|
||||
human_time(now.tv_sec - px->last_change, 1),
|
||||
(px->lbprm.tot_weight > 0 || !px->srv) ? "UP" : "DOWN",
|
||||
px->lbprm.tot_weight * px->lbprm.wmult,
|
||||
px->lbprm.tot_weight * px->lbprm.wmult / px->lbprm.wdiv,
|
||||
px->srv_act, px->srv_bck);
|
||||
|
||||
chunk_printf(&msg, sizeof(trash),
|
||||
@ -918,7 +918,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri,
|
||||
px->failed_conns, px->failed_resp,
|
||||
px->retries, px->redispatches,
|
||||
(px->lbprm.tot_weight > 0 || !px->srv) ? "UP" : "DOWN",
|
||||
px->lbprm.tot_weight * px->lbprm.wmult,
|
||||
px->lbprm.tot_weight * px->lbprm.wmult / px->lbprm.wdiv,
|
||||
px->srv_act, px->srv_bck,
|
||||
px->down_trans, now.tv_sec - px->last_change,
|
||||
px->srv?be_downtime(px):0,
|
||||
|
Loading…
x
Reference in New Issue
Block a user