Greetings,
I have reproduced this same issue on haproxy-1.4.6.
Configure a backend with
balance url_param x
hash-type consistent
server s1 host1:80
server s2 host2:80
server s3 host3:80
server s4 host4:80
The server will only dispatch requests to two servers.
The problem is seen in chash_init_server_tree:
/* queue active and backup servers in two distinct groups */
for (srv = p->srv; srv; srv = srv->next) {
srv->lb_tree = (srv->state & SRV_BACKUP) ? &p->lbprm.chash.bck : &p-
>lbprm.chash.act;
srv->lb_nodes_tot = srv->uweight * BE_WEIGHT_SCALE;
srv->lb_nodes_now = 0;
srv->lb_nodes = (struct tree_occ *)calloc(srv->lb_nodes_tot,
sizeof(struct tree_occ));
for (node = 0; node < srv->lb_nodes_tot; node++) {
srv->lb_nodes[node].server = srv;
srv->lb_nodes[node].node.key = chash_hash(srv->puid *
SRV_EWGHT_RANGE + node);
}
if (srv_is_usable(srv->state, srv->eweight))
chash_queue_dequeue_srv(srv);
}
The problem is that when this code runs, all of the servers have the
same srv->puid == 0.
With equal weights, each server generates the exact same set of node
keys.
Regardless of the key you lookup using eb32_lookup_ge, you get a node
for the last server.
The chash_get_server_hash function is reduced to choosing between the
closer of the last or first server.
Any insights as to why srv->puid is zero and not unique per server?
Jeff Persch