栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java按照权重比列分配任务实现

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java按照权重比列分配任务实现

题目:

有三个处理服务器A,B,C,权重比为2:3:5,要求根据权重比进行分配任务

方案: 1、随机权重分配

根据权重比列,随机生成区间数量来分配,这种有概率,分配量不是百分百按权重来

实现方式:
通过权重生成大小为权重和的数组,比如三台处理机器A,B,C权重比为 2 : 3 :5,由在10内随机生成数来决定取列表那个位置。
因为数组内的每个服务器数量是按照权重来的,所以只要数量足够大,取得的服务器概率理论上是无限接近于权重比的

2、权重分配

加权轮询,分为两种。
(1)一种是普通的
保证任务总数内的任务是按权重比进行分配的,但是可能会导致大量的任务在短时间内分配给一台。比如10个任务,A分配2个,B分配3个,C分配5个,但是在顺序上可能C的5个在一起,然后前面5个任务全部给了C,A和B一个都没,只有当任务第六个的时候才会分配给A或B

实现方式:
就是生成一个大小为权重总和的服务器List,里面每个服务器的元素数量由权重值决定,每次获取索引都加一,如果满了就重置从0开始

(2)一种是平滑加权轮询
保证任务总数内的任务是按权重比进行分配的,且顺序上比较均衡,比如10个任务,A分配2个,B分配3个,C分配5个,第一个是C,第二个是B,第三个是A,再一直往下。

实现方式:
所谓权重,可以理解为能力大小不均衡,从数字角度来看,就是每次递增的大小不一,递减大小一样,那次操作每个服务器的【当前权重】都自增【权重值】(初始固定值),取当前权重最大的一个,被选中则当前权重要减去【权重总和】(初始固定值)。

实现:
import com.nw.test.pojo.ServerNode;
import java.util.*;


public class WeightedRobinServiceImpl {
    private final List serverNodeList;
    private int index;
    private final int weightTotal;

    public WeightedRobinServiceImpl(List list) {
        this.index = 0;
        this.serverNodeList = list;
        this.weightTotal = list.stream().mapToInt(ServerNode::getWeight).sum();
    }

    
    public synchronized String smoothSelectServer() {
        if (serverNodeList.isEmpty()) {
            return null;
        }
        ServerNode maxServerNode = serverNodeList.stream().max(Comparator.comparingInt(ServerNode::getCurrentWeight)).get();
        serverNodeList.forEach(serverNode -> {
        
          / * 参考其它文章的话,节点还有一个偏移权重属性,初始值为权重值,这个偏移权重是用来实时调整服务器能力的,
     		* 每次选举的时候,当前权重就要加上偏移权重,每次选择了这个服务器,但是这个服务器响应失败(比如请求堵塞、网络波动),那么就把他的偏移值减一
     		* 相反,选择这个服务器响应成功(说明服务器响应能力变好或至少没变差),那么他的偏移值就加1,但是不能超过权重值
     		* 我们这里测试模拟的肯定没有响应失败的情况,所以不要偏移权重字段,直接也是加的权重值(固定,标识响应能力一直不变)
     		* /
            serverNode.setCurrentWeight(serverNode.getCurrentWeight() + serverNode.getWeight());
            if (serverNode.equals(maxServerNode)) {
                serverNode.setCurrentWeight(serverNode.getCurrentWeight() - weightTotal);
            }
        });
        return maxServerNode.getIp();

    }

    
    public synchronized String selectServer() {
        if (serverNodeList.isEmpty()) {
            return null;
        }
        List nodeList = new ArrayList<>();
        serverNodeList.forEach(serverNode -> {
            Integer weight = serverNode.getWeight();
            for (int i = 0; i < weight; i++) {
                nodeList.add(serverNode.getIp());
            }
        });
        if (index >= nodeList.size()) {
            index = 0;
        }
        String s = nodeList.get(index);
        index++;
        return s;

    }

        
	    public synchronized String randomSelectServer() {
	        if (serverNodeList.isEmpty()) {
	            return null;
	        }
	        List nodeList = new ArrayList<>();
	        serverNodeList.forEach(serverNode -> {
	            Integer weight = serverNode.getWeight();
	            for (int i = 0; i < weight; i++) {
	                nodeList.add(serverNode.getIp());
	            }
	        });
	        Random random = new Random();
	        // 在权重范围内随机
	        int n = random.nextInt(weightTotal);
	        return nodeList.get(n);
	    }
		

}
节点类
public class ServerNode {
    
    private String ip;
    
    private Integer weight;
    
    private Integer currentWeight;

    public ServerNode(String ip, Integer weight) {
        this.ip = ip;
        this.weight = weight;
        this.currentWeight = weight;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public Integer getCurrentWeight() {
        return currentWeight;
    }

    public void setCurrentWeight(Integer currentWeight) {
        this.currentWeight = currentWeight;
    }


    @Override
    public String toString() {
        return "ServerNode{" +
                "ip='" + ip + ''' +
                ", weight=" + weight +
                ", currentWeight=" + currentWeight +
                '}';
    }
}
测试:
 @Test
    void weightedRobinServiceTest() {
        List list = new ArrayList<>();
        list.add(new ServerNode("192.168.0.1", 2));
        list.add(new ServerNode("192.168.0.2", 3));
        list.add(new ServerNode("192.168.0.3", 5));

    WeightedRobinServiceImpl weightedRobinService = new WeightedRobinServiceImpl(list);

    Scanner scanner = new Scanner(System.in);
    while (true){
        System.out.println("请输入需要处理的数量: ");
        if (scanner.hasNext()) {
            List arr = new ArrayList<>();
            int amount = scanner.nextInt();
            if (amount == 9999) {
                weightedRobinService.unload();
                break;
            }
            for (int i = 0; i < amount; i++) {
                // String s = weightedRobinService.smoothSelectServer();
                //   String s = weightedRobinService.selectServer();
                String s = weightedRobinService.randomSelectServer();
                System.out.println(s);
                arr.add(s);
            }
            Map collect = arr.stream().collect(Collectors.groupingBy(s -> s, Collectors.counting()));
            collect.forEach((key, value)->{
                System.out.println("处理服务器ip: "+key+", 次数为:"+value);
            });
            System.out.println("---------------------------------------------");
        }
    }
}

------------------平滑加权轮询--------------------------
结果是相对分散的

------------------普通加权--------------------------
他的结果是集中的

------------------随机加权--------------------------

参考:
https://blog.csdn.net/loveyour_1314/article/details/121781952
https://my.oschina.net/u/4047016/blog/4420117

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/988934.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号