mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-25 07:41:36 +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 recount_servers(struct proxy *px);
|
||||||
void recalc_server_map(struct proxy *px);
|
void recalc_server_map(struct proxy *px);
|
||||||
int be_downtime(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
|
* 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_weight; /* total effective weight of servers participating to LB */
|
||||||
int tot_used; /* total number of servers used for LB */
|
int tot_used; /* total number of servers used for LB */
|
||||||
int wmult; /* ratio between user weight and effective weight */
|
int wmult; /* ratio between user weight and effective weight */
|
||||||
|
int wdiv; /* ratio between effective weight and user weight */
|
||||||
struct {
|
struct {
|
||||||
struct server **srv; /* the server map used to apply weights */
|
struct server **srv; /* the server map used to apply weights */
|
||||||
int rr_idx; /* next server to be elected in round robin mode */
|
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;
|
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
|
* 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
|
* 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.wmult = 1; /* default weight multiplier */
|
||||||
|
curproxy->lbprm.wdiv = 1; /* default weight divider */
|
||||||
|
|
||||||
/* now, newsrv == curproxy->srv */
|
init_server_map(curproxy);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curproxy->options & PR_O_LOGASAP)
|
if (curproxy->options & PR_O_LOGASAP)
|
||||||
curproxy->to_log &= ~LW_BYTES;
|
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 */
|
/* act, bck */
|
||||||
"<td>%s</td><td>%s</td>"
|
"<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",
|
||||||
(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 */
|
/* weight, active, backup */
|
||||||
"%d,%d,%d,"
|
"%d,%d,%d,"
|
||||||
"",
|
"",
|
||||||
sv->uweight,
|
sv->eweight * px->lbprm.wmult / px->lbprm.wdiv,
|
||||||
(sv->state & SRV_BACKUP) ? 0 : 1,
|
(sv->state & SRV_BACKUP) ? 0 : 1,
|
||||||
(sv->state & SRV_BACKUP) ? 1 : 0);
|
(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,
|
px->retries, px->redispatches,
|
||||||
human_time(now.tv_sec - px->last_change, 1),
|
human_time(now.tv_sec - px->last_change, 1),
|
||||||
(px->lbprm.tot_weight > 0 || !px->srv) ? "UP" : "DOWN",
|
(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->srv_act, px->srv_bck);
|
||||||
|
|
||||||
chunk_printf(&msg, sizeof(trash),
|
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->failed_conns, px->failed_resp,
|
||||||
px->retries, px->redispatches,
|
px->retries, px->redispatches,
|
||||||
(px->lbprm.tot_weight > 0 || !px->srv) ? "UP" : "DOWN",
|
(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->srv_act, px->srv_bck,
|
||||||
px->down_trans, now.tv_sec - px->last_change,
|
px->down_trans, now.tv_sec - px->last_change,
|
||||||
px->srv?be_downtime(px):0,
|
px->srv?be_downtime(px):0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user