采用类似nginx的权限轮询调度逻辑(WeightedRound-RobinScheduling),大概思路:遍历整个服务器结合,将节点服务器currentWeight值加上预设权重值(使之节点权重提升),找出整个集合currentWeight权重最大的节点作为选中节点(集合中权重最大的服务器),最后将选中节点currentWeight减去totalWeight(使之节点权重降低,下次其他节点有机会上任)。每次获取服务器节点时依次执行。
代码如下:

import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;

import java.util.List;

/**
 * 权重轮询调度算法,参考nginx负载均衡实现(WeightedRound-RobinScheduling)
 *
 * @author Jianbo.Peng
 * @date 2021/8/24 1:25 下午
 */
public class WeightedRoundRobinScheduling {

    private List<ServerWeightConf> servers;
    private long totalWeight;

    public WeightedRoundRobinScheduling(List<ServerWeightConf> servers) {
        this.servers = servers;
        totalWeight = servers.stream()
                .mapToLong(ServerWeightConf::getWeight)
                .sum();
    }

    public ServerWeightConf getBestServer() {
        ServerWeightConf server;
        ServerWeightConf best = null;

        for (int i = 0, len = servers.size(); i < len; i++) {
            server = servers.get(i);
            server.currentWeight += server.weight;

            if (best == null || server.currentWeight > best.currentWeight) {
                best = server;
            }
        }
        if (best == null) {
            return null;
        }

        best.currentWeight -= totalWeight;
        return best;
    }

    @ToString
    @Data
    @RequiredArgsConstructor
    public static class ServerWeightConf {
        @NonNull
        private String ip;
        @NonNull
        //服务器预设权重值
        private int weight;
        //当前服务器执行的权重值
        private long currentWeight;
    }
}

测试类:

public class TestClass {

    @Test
    public void testBestServer() {
        List<ServerWeightConf> servers = new ArrayList<>();
        servers.add(new ServerWeightConf("192.168.1.2", 30));
        servers.add(new ServerWeightConf("192.168.1.3", 60));
        servers.add(new ServerWeightConf("192.168.1.4", 10));

        Map<String, Integer> statMap = new HashMap<>();
        WeightedRoundRobinScheduling wrrs = new WeightedRoundRobinScheduling(servers);
        for (int i = 0; i < 100; i++) {
                        ServerWeightConf server = wrrs.getBestServer();
            int count = statMap.getOrDefault(server.getIp(), 0);
            statMap.put(server.getIp(), count + 1);
        }

        System.out.println("执行请求权重:");
        for (String ip : statMap.keySet()) {
            System.out.println("服务器:" + ip + "\t请求数:" + statMap.get(ip));
        }
    }
}

执行结果:

执行请求权重:
服务器:192.168.1.3    请求数:60
服务器:192.168.1.2    请求数:30
服务器:192.168.1.4    请求数:10
最后修改:2022 年 09 月 03 日
如果觉得我的文章对你有用,请随意赞赏