Nginx负载均衡代码之加权轮询
2016-01-07 10:40
477 查看
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:
主服务器群轮询失败,则在备用服务器中进行轮询。
2) ngx_http_upstream_get_peer:
轮询阶段,将对所有服务器进行遍历,对于已经尝试过、下线、失败次数超过限制的服务器不参与实际轮询过程。
轮询实际计算过程比较简单,单纯是对有效权重的计算和恢复。
当服务器全都有效时(也没有超时等异常),所有服务器的有效权重值不变,每轮轮询时候的总有效权重都一样,基础权重值越大的服务器在当前权重为负数时恢复越快,重新激活的频率也越高。
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中,当调度后的服务器执行失败后,会通过对权重的控制来简单控制服务器状态。
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 |= 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代理服务器的磁盘IO使用率,提高转发性能
- LNMP实现(CentOS7+Nginx-1.9.4+PHP-5.6+MySQL-5.6.26)
- Nginx+Keepalived实现
- nginx压力测试使用webbench
- 阿里云服务器使用OneinStack的lnmp一键安装包后查看nginx的并发数
- nginx queue设计
- Nginx配置文件详细说明
- Nginx服务器中为网站或目录添加认证密码的配置详解
- nginx的配置问题
- nginx配置文件强制下载
- django+uwsgi+nginx ajax post 504 Gateway Time-out
- Windows系统下安装配置Nginx
- CentOS6下基于Nginx搭建mp4/flv流媒体服务器(可随意拖动)并支持RTMP/HLS协议(含转码工具)
- nginx常见502问题的解决
- linux下安装nginx
- Nginx使用
- Java项目部署总结(三)nginx安装与配置
- 统计5分钟内Nginx访问量及平均相应时间
- 虚拟机上CentOS 7.0编译安装Nginx+MySQL+PHP(二)
- Nginx基本配置、性能优化指南