springboot实现加权轮询

/**
 * 服务器地址分配(平滑加权轮询)
 * @author wangxiao
 * @date 2020-12-12
 **/
@Component
public class SmoothWeightRoundRobinLoadBalance {

    /**
     * 按权重均分
     */
    private boolean averageWeight = true;

    /**
     * 总权重
     */
    private int totalWeight;

    /**
     * 可调用服务器集合
     */
    private List<Invoker> invokers;

    private final Object lock = new Object();

    /**
     * 初始构造可调用服务器集合并计算总权重
     */
    public SmoothWeightRoundRobinLoadBalance() {
        List<Invoker> invokers = new ArrayList<>();
        List<OJServerAddress> addressList = MokitConfig.getAddress();
        for (OJServerAddress address:addressList
             ) {
            invokers.add(new Invoker(address.getIp(),address.getPort(),address.getWeight()));
        }
        this.invokers = invokers;
        for (int i = 0; i < invokers.size(); i++) {
            Invoker invoker = invokers.get(i);
            if (averageWeight && i > 0 && invoker.getWeight() != invokers.get(i - 1).getWeight()) {
                averageWeight = false;
            }
            totalWeight += invoker.getWeight();
        }
    }

    /**
     * 选择执行服务器
     * @param msg 业务信息
     * @return
     * @author wangxiao
     * @date 2020-12-15
     */
    public Invoker selectHost(){
        List<Invoker> list = getInvokers();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        if (list.size() == 1) {
            return list.get(0);
        }
        return doSelect();
    }

    private List<Invoker> getInvokers(){
        return invokers;
    }

    /**
     * 执行
     * @param msg 业务信息
     * @return
     * @author wangxiao
     * @date 2020-12-15
     */
    private Invoker doSelect() {
        if (averageWeight || totalWeight < 1) {
            return doSelect(msg);
        }
        synchronized (lock) {
            Invoker doInvoker = selectInvoker(invokers);
            before(doInvoker);
       return doInvoker; } } /** * 选择执行业务的服务器 * @param invokers 可调用服务器集合 * @return * @author wangxiao * @date 2020-12-15 */ private Invoker selectInvoker(List<Invoker> invokers) { Invoker maxCurrentInvoker = invokers.get(0); for (Invoker invoker : invokers) { invoker.setCurrentWeight(invoker.getWeight() + invoker.getCurrentWeight()); if (maxCurrentInvoker.getCurrentWeight() < invoker.getCurrentWeight()) { maxCurrentInvoker = invoker; } } return maxCurrentInvoker; } private void before(Invoker doInvoker) { doInvoker.setCurrentWeight(doInvoker.getCurrentWeight() - totalWeight); } }
/**
 * @author wangxiao
 * @Date 2020-12-12
 **/
public class Invoker {
    /**
     * ip地址
     */
    private String ip;
    /**
     * 端口
     */
    private Integer port;
    /**
     * 权重
     */
    private int weight;
    /**
     * 当前权重
     */
    private int currentWeight = 0;

    public String getIp() {
        return ip;
    }

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

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public int getWeight() {
        return weight;
    }

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

    public int getCurrentWeight() {
        return currentWeight;
    }

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

    public Invoker(String ip, int port,int weight) {
        this.ip = ip;
        this.weight = weight;
        this.port = port;
    }

    @Override
    public String toString() {
        return "Invoker{" +
                "ip='" + ip + '\'' +
                ", port=" + port +
                ", weight=" + weight +
                ", currentWeight=" + currentWeight +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Invoker invoker = (Invoker) o;
        return weight == invoker.weight &&
                currentWeight == invoker.currentWeight &&
                Objects.equals(ip, invoker.ip) &&
                Objects.equals(port, invoker.port);
    }

    @Override
    public int hashCode() {
        return Objects.hash(ip, port, weight, currentWeight);
    }
}

调用

@Autowired
private SmoothWeightRoundRobinLoadBalance smoothWeightRoundRobinLoadBalance;

smoothWeightRoundRobinLoadBalance.selectHost();

 参考链接:https://blog.csdn.net/dongguabai/article/details/106990409

posted @ 2020-12-15 11:17  xiaoWangxiao  阅读(613)  评论(0编辑  收藏  举报