平滑加权负载均衡算法

算法描述


假设有 N 台服务器 S = {S0, S1, S2, …, Sn},默认权重为 W = {W0, W1, W2, …, Wn},当前权重为 CW = {CW0, CW1, CW2, …, CWn}。在该算法中有两个权重,默认权重表示服务器的原始权重,当前权重表示每次访问后重新计算的权重,当前权重的出初始值为默认权重值,当前权重值最大的服务器为 maxWeightServer,所有默认权重之和为 weightSum,服务器列表为 serverList,算法可以描述为:
1、找出当前权重值最大的服务器 maxServer
2、计算 {W0, W1, W2, …, Wn} 之和 sumBlance
3、将 maxServer.CW = maxServer.CW - sumBlance;
4、重新计算 {S0, S1, S2, …, Sn} 的当前权重 CW,计算公式为 Sn.CW = Sn.CW + Sn.Wn
5、返回 maxServer

 

状态描述:

初始状态:5,2,2

  配置前权重 选择序号 配置后权重 原始权重
1 5,2,2 0 -4,2,2 5,2,2
2 1,4,4 1 1,-5,4 5,2,2
3 6,-3,6 0 -3,-3,6 5,2,2
4 2,-1,8 2 2,-1,-1 5,2,2
5 7,1,1 0 -2,1,1 5,2,2

程序实现:

package com.jike.alg.bigData;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @program: jike_study
 * @description:加权平滑负载均衡
 * @author: dyingstraw
 * @create: 2019-07-05 10:01
 **/
public class AvgLoadBalance {

    class LoadServer{
        /**
         * 当前权重
         */
        private int currentWeight;
        /**
         * 原始权重
         */
        private int originWeight;
        /**
         * 服务名
         */
        private String name;

        public LoadServer( String name,int currentWeight) {
            this.currentWeight = currentWeight;
            this.originWeight = currentWeight;
            this.name = name;
        }

        public int getCurrentWeight() {
            return currentWeight;
        }

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

        public int getOriginWeight() {
            return originWeight;
        }

        public void setOriginWeight(int originWeight) {
            this.originWeight = originWeight;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("{");
            sb.append("\"classname\":\"LoadServer\",");
            sb.append("\"currentWeight\":")
                    .append(currentWeight);
            sb.append(",\"originWeight\":")
                    .append(originWeight);
            sb.append(",\"name\":\"")
                    .append(name).append('\"');
            sb.append('}');
            return sb.toString();
        }
    }

    private Map<String,LoadServer> serverMap = new ConcurrentHashMap<>();
    public void initServerWeight(){
        serverMap.put("101",new LoadServer("101",5));
        serverMap.put("102",new LoadServer("102",2));
        serverMap.put("103",new LoadServer("103",2));
    }


    /**
     * 选择最优负载
     * @return
     */

    public LoadServer selectBestServer(){


        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("\t");
        for (Map.Entry<String,LoadServer> server:serverMap.entrySet()){
            stringBuilder.append(server.getValue().currentWeight+",");
        }
        stringBuilder.append("\t\t");
        System.out.println("\t配置前\t\t配置后\t最优配置名称");



        int sumBalance = 0;
        LoadServer maxServer=null;
        for (Map.Entry<String,LoadServer> server:serverMap.entrySet()){
            /** 求总负载 **/
            sumBalance+=server.getValue().originWeight;
            /** 求当前时刻最大权重的负载 **/
            if (maxServer==null){
                maxServer = server.getValue();
            }else {
                if (server.getValue().getCurrentWeight()>maxServer.getCurrentWeight()){
                    maxServer = server.getValue();
                }
            }
        }
        /** 找到最大负载之后,恒心当前负载 **/
        maxServer.setCurrentWeight(maxServer.getCurrentWeight()-sumBalance);

        for (Map.Entry<String,LoadServer> server:serverMap.entrySet()){
           server.getValue().setCurrentWeight(server.getValue().getCurrentWeight()+server.getValue().getOriginWeight());
           stringBuilder.append(server.getValue().getCurrentWeight()+",");
        }
        stringBuilder.append("\t"+maxServer.getName());
        System.out.println(stringBuilder);
        System.out.println("--------------------------------\n");

        return maxServer;

    }

    public static void main(String[] args) {
        AvgLoadBalance balance = new AvgLoadBalance();
        balance.initServerWeight();
        for (int i =0;i<10;i++){
            balance.selectBestServer();
        }
    }

}

执行结果

"D:\Program Files\Java\jdk1.8.0_121\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=12734:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_121\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\zipfs.jar;D:\Pro
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值