微服务架构-高性能Netty服务器-067:手写RPC负载均衡器五种算法

1 手写RPC负载均衡器五种算法演示

课程内容:
1.负载均衡器在RPC调用中实现的作用
2.五种RPC框架负载均衡器的种类
3.基于策略模式设计负载均衡器
4.手写五种负载均衡器算法

2 负载均衡器在RPC框架实现的作用

Rpc是远程调用技术 dubbo、feign、httpclient
任何rpc框架都必须有本地负载均衡器eg:ribbon,dubbo自带负载均衡器
负载均衡器在rpc中作用?
能够提高生产者服务器集群访问,分摊压力。
原理:从一个集合列表地址元素中,采用负载均衡器算法最终获取一个地址实现调用。
负载均衡算法:轮询、权重、一致性hash、随机权重、随机

3 手写负载均衡器轮询机制第一种算法

public interface LoadBalancer<T> {

    // 从一个集群地址中获取单个rpc调用地址
    String getAddress(List<T> address);
}
public class RotationLoadBalancer implements LoadBalancer<String> {

    private int index;

    public synchronized String getAddress(List<String> address) {
        if (index >= address.size()) {
            // 重置为0
            index = 0;
        }
        String value = address.get(index++);
        System.out.println("value:" + value);
        return value;
    }
}
public class Test001 {
    public static void main(String[] args) {
        LoadBalancer loadBalancer = new RotationLoadBalancer();
        ArrayList<String> strings = new ArrayList<String>();
        strings.add("127.0.0.1:8080");
        strings.add("127.0.0.1:8081");
        loadBalancer.getAddress(strings);
        loadBalancer.getAddress(strings);
        loadBalancer.getAddress(strings);
        loadBalancer.getAddress(strings);
    }
}

运行结果:
在这里插入图片描述

4 手写负载均衡器轮询机制第二种算法

public class RotationLoadBalancer2 implements LoadBalancer<String> {

    // 原子类计数器,从0开始计数
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    public String getAddress(List<String> address) {
        String value = address.get(atomicInteger.incrementAndGet() % address.size());
        System.out.println("value:" + value);
        return value;
    }
}
public class Test002 {
    public static void main(String[] args) {
        LoadBalancer loadBalancer = new RotationLoadBalancer2();
        ArrayList<String> strings = new ArrayList<String>();
        strings.add("127.0.0.1:8080");
        strings.add("127.0.0.1:8081");
        loadBalancer.getAddress(strings);
        loadBalancer.getAddress(strings);
        loadBalancer.getAddress(strings);
        loadBalancer.getAddress(strings);
    }
}

运行结果:
在这里插入图片描述
轮询机制算法两种写法:

  1. 使用index实现自增,注意判断index不要越界
  2. 访问的次数 % 列表长度

5 手写负载均衡器权重设计算法

权重算法原理就是根据权重的大小实现排序,重新生成一个新的集合。
权重轮询
127.0.0.1:8080 weight 1
127.0.0.1:8081 weight 2
address[0]= 127.0.0.1:8080
address[1]= 127.0.0.1:8081
address[2]= 127.0.0.1:8081

@Data
@AllArgsConstructor
public class WeightEntity {

    /**
     * 地址
     */
    private String address;

    /**
     * 权重大小
     */
    private int weight;
}
public class WeightLoadBalancerUtils {

    // 对集合权重实现排序
    public static List<String> weightToRotation(List<WeightEntity> listWeight) {
        ArrayList<String> listAddress = new ArrayList<String>();
        for (int i = 0; i < listWeight.size(); i++) {
            // 获取配置的权重大小
            WeightEntity weightEntity = listWeight.get(i);
            for (int j = 0; j < weightEntity.getWeight(); j++) {
                listAddress.add(listWeight.get(i).getAddress());
            }
        }
        return listAddress;
    }
}
public class WeightLoadBalancer implements LoadBalancer<WeightEntity> {

    private int index;

    public synchronized String getAddress(List<WeightEntity> addresss) {
        List<String> strings = WeightLoadBalancerUtils.weightToRotation(addresss);
        if (index >= strings.size()) {
            // 重置为0
            index = 0;
        }
        String value = strings.get(index++);
        System.out.println("value:" + value);
        return value;
    }
}
public class Test003 {
    public static void main(String[] args) {
        ArrayList<WeightEntity> weightEntities = new ArrayList<WeightEntity>();
        weightEntities.add(new WeightEntity("127.0.0.1:8080",1));
        weightEntities.add(new WeightEntity("127.0.0.1:8081",2));
        WeightLoadBalancer loadBalancer = new WeightLoadBalancer();
        loadBalancer.getAddress(weightEntities);
        loadBalancer.getAddress(weightEntities);
        loadBalancer.getAddress(weightEntities);
        loadBalancer.getAddress(weightEntities);
        loadBalancer.getAddress(weightEntities);
        loadBalancer.getAddress(weightEntities);
    }
}

运行结果:
在这里插入图片描述

6 手写负载均衡器一致性hash算法

一致性hash用户ip绑定 相同ip获得地址不变

public class IpHashLoadBalancer {

    public String getAddress(List<String> address, String ipAddr) {
        String vaule = address.get(ipAddr.hashCode() % address.size());
        System.out.println("value:" + vaule);
        return vaule;
    }
}
public class Test004 {
    public static void main(String[] args) {
        IpHashLoadBalancer ipHashLoadBalancer = new IpHashLoadBalancer();
        ArrayList<String> strings = new ArrayList<String>();
        strings.add("127.0.0.1:8080");
        strings.add("127.0.0.1:8081");
        ipHashLoadBalancer.getAddress(strings,"192.168.0.1");
        ipHashLoadBalancer.getAddress(strings,"192.168.0.1");
        ipHashLoadBalancer.getAddress(strings,"192.168.0.2");
        ipHashLoadBalancer.getAddress(strings,"192.168.0.2");
    }
}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值