JAVA权重算法(如Dubbo的负载均衡权重)

首先了解一下负载均衡。

百度百科:

负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。

个人理解,负载均衡,顾名思义,就是让硬件或服务,所受的负载,尽量均衡一点。

物尽其用,如250G固态硬盘和1T机械硬盘。

作为系统盘,则选择用250G的固态,读取和写入的速度块。

有很多学习资源要存,容量较大,那么就会1T的机械硬盘。

择优选择,打疫苗时,A,B,C三个医院,A医院爆满,C医院人数较少,那么就去C医院。

Dubbo四种负载均衡


①:随机权重(Random LoadBalance)。(dubbo默认)
A:权重40  占比2/5
B:权重20  占比1/5
C:权重40  占比2/5
则每次请求,都是随机访问的,可能A,可能B,可能C。数据量大的情况下,就会形成权重的比例。

②:轮询(RoundRobin LoadBalance)
轮循,按公约后的权重设置轮循比率。(可以根据权重轮询,如2/5,1/5,2/5。5个请求,则 A-B-C-A-C)无权重则A-B-C-A-B-C....
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。

③:最少活跃调用数(LeastActive LoadBalance)
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
A:200ms
B:200ms
C:300ms
先看一下上次调用时间,请求优先调用A和B,随机选择。统计上一次的调用时间

④:一致性hash(ConsistentHash LoadBalance)
一致性 Hash,相同参数的请求总是发到同一提供者。
当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。
算法参见:http://en.wikipedia.org/wiki/Consistent_hashing
缺省只对第一个参数 Hash,如果要修改,请配置 <dubbo:parameter key="hash.arguments" value="0,1" />
缺省用 160 份虚拟节点,如果要修改,请配置 <dubbo:parameter key="hash.nodes" value="320" />

方法名,和第一个参数名,getUser?id=1,调用服务A,则下次同方法同参数,会继续调用服务A,除非服务A挂掉,那么就会根据虚拟节点,平摊给其他服务提供者。算法处理。

 

个人理解的权重算法
 

 /**
  * <h3>根据权重获取对应服务,传入服务:权重map</h3>
  *
  * @param map 服务:权重map
  * @return java.lang.String
  * @author Hubers 
  * @date 2021/6/15 16:16
  **/
 public static String getServerByWeight(Map<String, Integer> map) {
        if (map.isEmpty()){
            return null;
        }
        Integer total = 0;
        // 计算所有权重,如100+200+300=600
        for (Integer value : map.values()) {
            total += value;
        }
        Random random = new Random();
        // 在权重范围内随机,600以内随机
        int nextInt = random.nextInt(total);

        // 遍历所有服务提供者provide的ip地址
        for (String ip : map.keySet()) {
            // 取出权重值
            Integer weight = map.get(ip);

            // 权重在范围内,则返回对应ip
            if (nextInt < weight) {
                return ip;
            }
            // 否则减去权重,继续下一次循环,匹配对应的ip
            nextInt -= weight;
        }
        return null;
    }


public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("192.168.1.1", 10);
        map.put("192.168.1.2", 10);
        map.put("192.168.1.3", 10);
        map.put("192.168.1.4", 10);
        for (int i = 0; i < 10; i++) {
            String weight = getServerByWeight(map);
            if (Objects.isNull(weight)) {
                throw new RuntimeException("无可用服务");
            }
            System.out.println(weight);
        }
    }

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值