给上一篇博文填个坑,讲解下负载均衡算法中最常见的加权随机算法
加权随机算法
负载均衡的一种算法实现,效果是按服务的权重设置,非顺序地请求资源服务。
源码分析
Dubbo的负载均衡算法实现,放在org.apache.dubbo.rpc.cluster包下,以org.apache.dubbo.rpc.cluster.LoadBalance定义,通过SPI功能动态加载,默认实现为org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance(加权随机)
源码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) { int length = invokers.size(); boolean sameWeight = true; int[] weights = new int[length]; int totalWeight = 0; for (int i = 0; i < length; i++) { int weight = getWeight(invokers.get(i), invocation); totalWeight += weight; weights[i] = totalWeight; if (sameWeight && totalWeight != weight * (i + 1)) { sameWeight = false; } } if (totalWeight > 0 && !sameWeight) { int offset = ThreadLocalRandom.current().nextInt(totalWeight); for (int i = 0; i < length; i++) { if (offset < weights[i]) { return invokers.get(i); } } } return invokers.get(ThreadLocalRandom.current().nextInt(length)); }
|
源码分析
首先Dubbo会轮训所调用资源服务的所有实例,计算所有服务的静态权重之和(totalWeight),使用0到totalWeight建立一个一位坐标系,将所有服务按照权重值分配到坐标系的每个节点
例:目前有A、B、C三个服务,权重配置分别为A=10、B=20、C=10
则A、B、C会分别位于距离坐标系原点10、30、40的位置,如下图

在所有服务的权重之和(totalWeight)范围内建立一个一位坐标系,以0为下限以totalWeight为上限取随机数,当随机数落点在服务各自的范围内时,则对应的服务作为选举结果
实例演示
没有,自己脑补吧