# nodejs负载均衡(二):RPC负载均衡

1,962 阅读3分钟

简介

这一篇确实拖的比较久,上节讲了服务负载均衡实现,但是如果需要调用远程服务, 如何保证不是调用不会集中在一台服务上,如何确保远程服务调用的负载均衡? 这就要实现 Consumer 端调用rpc的负载均衡。所以本文章主要讲解 RPC负载均衡算法实现

未命名文件 (1).jpg

算法

下面介绍几个主要的负载均衡算法如何实现,可以看下我写的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对数据池长度数取模,获取到下一个节点下标

缺点:

  • 要求服务提供节点性能一致

load balancer-Page-1.png

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]

load balancer-Page-2.png

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值比较哪个值最相近,决定访问哪个节点

load balancer-Page-7.png
load balancer-Page-5.png

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) 算法,连接数最少服务节点优先调用。

  • 需要统计连接或请求数
  • 服务器性能一致

load balancer-Page-3.png

Weighted Least Connections

权重最少连接(Weighted least connections) 算法,基于最少连接服务节点增加权重判断。

load balancer-Page-4.png

这篇文章也憋了很久,本来想一篇文章写完 rpc ,但是发现事情很多,想想还是分开写,后面再写一篇《nodejs负载均衡(三):RPC实现》

更多细节查看 NPM包 load-balancer-algorithm