简介
这一篇确实拖的比较久,上节讲了服务负载均衡实现,但是如果需要调用远程服务,如何保证不是调用不会集中在一台服务上,如何确保远程服务调用的负载均衡?这就要实现 Consumer
端调用 rpc 的负载均衡。所以本文章主要讲解 RPC 负载均衡算法实现。
算法
下面介绍几个主要的负载均衡算法如何实现,可以看下我写的 NPM 包 load-balancer-algorithm。
const LBA = require('load-balancer-algorithm');
const weightRandomPool = [{ host: "127.0.0.2", weight: 2},
{host: "127.0.0.1", weight: 3},
{host: "127.0.0.3", weight: 5},
];
const weightedList = []
const loadBalance = new LBA.WeightedRoundRobin(weightRandomPool);
for(let i = 0; i < 10; i++){const address = loadBalance.pick();
weightedList.push(loadBalance.getWeight(address.host))
}
// [5, 5, 3, 5, 2, 3, 5, 2, 3, 5]
console.log(weightedList)
Round Robin
轮询(Round robin) 算法,就是依次轮询服务队列的节点,周而复始,这个实现比较简单。
- 消费端调用均衡
- 通过当前下标 + 1 对数据池长度数取模,获取到下一个节点下标
缺点:
- 要求服务提供节点性能一致
Weighted Round Robin
权重轮询(Weighted round robin) 算法,基于轮询添加权重判断,这样可以针对性能低服务节点减少流量。
- 动态调整权重实时同步
- 相对比较均衡的算法
- 但是权重大服务节点会突然负载上升,所以又有出现
平滑权重轮询
(smooth Weighted Round Robin),就是平滑分布的获取节点
[{ host: "127.0.0.1", weight: 2},
{host: "127.0.0.2", weight: 3},
{host: "127.0.0.3", weight: 5},
]
// normal
// [5, 5, 5, 5, 5, 3, 3, 3, 2, 2]
// smooth
// [5, 5, 3, 5, 2, 3, 5, 2, 3, 5]
Source IP Hash
Source IP hash (consistent hash)算法,为了将客户端 IP 请求固定分配给一台服务器,实现获取同一个 session
,看下 带虚拟节点一致性 hash 实现,也目前主流推荐的。
- 通过节点
IP
生成 N 个hash
,然后通过hash
获取 N 个虚拟节点的值,然后通过与请求数据(ip 或参数)生成的hash
比较最相近的节点 - nodejs 主要
sticky sessions
模式使用,确保访问的都是同一个服务上的session
缺点:
- 相对其他算法,负载均衡性 较低,性能也相对较低
- 固定的 IP 服务挂了,用户
session
就会丢失,所以做好的方法还是session
共享
举例:如图每个节点生成 2 个虚拟节点,然后根据请求数据生成 hash 值比较哪个值最相近,决定访问哪个节点
Random
随机(Random) 算法,随机产生一个 pool
长度数范围内的整数,从而随机获取机器。
- 碰撞率高,但是调用量越大分布越平均
- 随机一个 0~pool.length 范围内的值
Weighted Random
权重随机(weighted random)算法,假如机器的性能不一致,这时候就要基于随机基础上添加权重计算。
- 随机一个 0~totalWeighted 值,然后通过依次减去
pool
的节点权重,如果小于 0,代表随机值落在当前权重范围中
let offset = randomInteger(totalWeight);
for (let i = 0; i < len; i++) {
// 随机值减去权重,属于哪一个权重片段
offset -= this.getWeight(pool[i]);
if (offset < 0) {address = pool[i];
break;
}
}
Least Connections
最少连接(Least connections) 算法,连接数最少服务节点优先调用。
- 需要统计连接或请求数
- 服务器性能一致
Weighted Least Connections
权重最少连接(Weighted least connections) 算法,基于最少连接服务节点增加权重判断。
这篇文章也憋了很久,本来想一篇文章写完 rpc
,但是发现事情很多,想想还是分开写,后面再写一篇《nodejs 负载均衡(三):RPC 实现》
更多细节查看 NPM 包 load-balancer-algorithm