[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:
Willy Tarreau 2007-11-19 19:10:18 +01:00
parent 2069704492
commit 5dc2fa660c
5 changed files with 61 additions and 50 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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,