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