1. 简介:
加权轮询以轮询的方式对不同的服务器进行调度,并不记录当前服务器的状态,是一种无状态的调度方法。在Nginx中,当调度后的服务器执行失败后,会通过对权重的控制来简单控制服务器状态。
2. 主要变量:
控制权重的主要三个变量:
1) weight:表示配置的权重原始值,不参与实际调度过程,主要用于当服务器执行失败以后的权重衰减后恢复过程的最大值。
2) effect_weight:当前权重的有效值,初始化时设置为配置的权重值,当调度到的服务器执行失败后,有效权重会衰减,并在后续调度过程中逐渐恢复。
3) current_weight:当前的权重值,每轮调度时会加上有效权重,当服务器被选择时,会衰减一个值(本轮有效总权重)。
3. 轮询过程:
轮询主要在两个函数中完成,ngx_http_upstream_get_round_robin_peer是主要入口,主要处理了单机场景以及轮询结果的返回。ngx_http_upstream_get_peer这个函数实现实际的轮询过程。
1) ngx_http_upstream_get_round_robin_peer:
if (peers->single) {
peer = &peers->peer[0];
if (peer->down) {
goto failed;
}
}
单机场景下如果唯一的一个服务器并没有下线,则直接返回该服务器。
failed:
if (peers->next) {
/* ngx_unlock_mutex(peers->mutex); */
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "backup servers");
rrp->peers = peers->next;
n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
/ (8 * sizeof(uintptr_t));
for (i = 0; i < n; i++) {
rrp->tried[i] = 0;
}
rc = ngx_http_upstream_get_round_robin_peer(pc, rrp);
if (rc != NGX_BUSY) {
return rc;
}
/* ngx_lock_mutex(peers->mutex); */
}
2) ngx_http_upstream_get_peer:
轮询阶段,将对所有服务器进行遍历,对于已经尝试过、下线、失败次数超过限制的服务器不参与实际轮询过程。
轮询实际计算过程比较简单,单纯是对有效权重的计算和恢复。
peer->current_weight += peer->effective_weight;
total += peer->effective_weight;
if (peer->effective_weight < peer->weight) {
peer->effective_weight++;
}
if (best == NULL || peer->current_weight > best->current_weight) {
best = peer;
}
选出最优值以后需要更新最优值当前的权重,减去所有轮询节点的有效权重值总和。
if (best == NULL) {
return NULL;
}
i = best - &rrp->peers->peer[0];
rrp->current = i;
n = i / (8 * sizeof(uintptr_t));
m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
rrp->tried[n] |= m;
best->current_weight -= total;
if (now - best->checked > best->fail_timeout) {
best->checked = now;
}
return best;
当服务器全都有效时(也没有超时等异常),所有服务器的有效权重值不变,每轮轮询时候的总有效权重都一样,基础权重值越大的服务器在当前权重为负数时恢复越快,重新激活的频率也越高。
4. Patch附带例子[2]:
a b c 对应权重为 5 1 1,期间有效权重不变。第一行为轮询完成,第二行为选择完成后的当前权重。
a b c
0 0 0 (initial state)
第一轮:
5 1 1 (a selected)
-2 1 1
第二轮:
3 2 2 (a selected)
-4 2 2
第三轮
1 3 3 (b selected)
1 -4 3
第四轮
6 -3 4 (a selected)
-1 -3 4
第五轮
4 -2 5 (c selected)
4 -2 -2
第六轮:
9 -1 -1 (a selected)
2 -1 -1
第七轮:
7 0 0 (a selected)
0 0 0
5. 参考文档:
[1]http://blog.csdn.net/zhangskd/article/details/50194069
[2]https://github.com/phusion/nginx/commit/27e94984486058d73157038f7950a0a36ecc6e35
本文介绍了Nginx中加权轮询负载均衡的工作原理,包括其无状态调度特性、主要变量如weight、effect_weight和current_weight的作用,以及轮询过程的详细步骤。文中还提供了一个权重分配的例子,展示不同权重服务器在轮询过程中的状态变化。

5168

被折叠的 条评论
为什么被折叠?



