负载均衡算法实现(权重随机、平滑轮询、一致性哈希

写在前面

通过客户端实现负载均衡算法(包括随机,轮询,一致性哈希),要求在客户端使用参数指定负载均衡策略和调用次数,调用不同的服务端。

  • 三台服务器,一台客户端
  • 由于只在一台机器上进行实现,三台服务器的不同由端口号来区分
  • 客户端,服务端均采用spring-boot暴露Restful接口

三种负载均衡策略

服务器列表

import java.util.*;

public class ServerPath {
   

    //不带权重的服务路径列表
    public static final List<String> LIST = Arrays.asList(
            "8081",
            "8082",
            "8083"
    );

    //带有权重的 服务路径 列表
    public static final Map<String,Integer> WEIGHT_LIST = new LinkedHashMap<>();
    static {
   
        WEIGHT_LIST.put("8081",20);
        WEIGHT_LIST.put("8082",30);
        WEIGHT_LIST.put("8083",50);
    }
}

随机算法

随机算法顾名思义,从一些服务器列表中随机挑选出一个服务器来进行负载操作,强调随机性。
但只是简单随机会有一些问题,如果我们有3台服务器,运算效率差距很大,第一台运算效率100分,第二台50分,第三台1分,那么我们简单随机的话,显然无法发挥第一台高性能服务器的优势,所以带权重的随机算法更加优秀。

  • 8081端口,权重20

  • 8082端口,权重30

  • 8083端口,权重50

  • 按权重构造一个长度为20+30+50的一维坐标轴,总和为100,则在0~100之间取一个随机数,根据随机数所在的区间来选择具体的服务器。

  • |0——8081——20|21———8082———50|51—————8083—————100|

  • 若随机数为 35, 则 20<35<50,选择8082端口服务器。

代码实现
import com.balanceLoad.client.ServerPath;

import java.util.Random;

public class RandomBalance {
   
    public static String getServerPath(){
   
        Random random = new Random();
        int total = 0;
        //从服务器端口列表中取权重累加到total
        for(Integer weight : ServerPath.WEIGHT_LIST.values()){
   
            total +=weight;
        }

        int x = random.nextInt(total);
        return GetPath.getPath(x);

    }

    public static void main(String[] args) {
   
        for(int i =0;i<10;i++){
   
            System.out.println(getServerPath());
        }
    }

}

GetPath类

public class GetPath {
   
    public static String getPath(int pos){
   
        for(String port : ServerPath.WEIGHT_LIST.keySet()){
   
            int weight = ServerPath.WEIGHT_LIST.get(port);
            if(pos<weight){
   
                return port;
            }
            pos -= weight;
        }
        return "";
    }
}

轮询算法(平滑加权轮询)

朴素的轮询方法,如果大权重的服务器排在前面,会造成对某台机器请求过多,而排在后面的服务器在请求数较少的时候,可能都没有机会参与负载。

例如权重100的服务器A排在首位,后面跟着权重20的服务B和权重5的服务器C,如果每次服务器集群运行期间请求数都小于100,那么BC服务器基本上都没法参与负载。

例如

  • 8081端口,权重20
  • 8082端口,权重30
  • 8083端口,权重50
  • 调用10次服务,朴素的轮询调用序列为:
8081
8081
8082
8082
8082
8083
8083
8083
8083
8083

使用平滑轮询,可以优化为如下序列:

8083
8082
8081
8083
8082
8083
8083
8081
8082
8083
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值