
com.github.df.restypass.lb.RoundRobinLoadBalancer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resty-pass Show documentation
Show all versions of resty-pass Show documentation
High-Performance Restful Client Library
package com.github.df.restypass.lb;
import com.github.df.restypass.command.RestyCommand;
import com.github.df.restypass.lb.server.ServerInstance;
import com.github.df.restypass.util.AtomicPositiveInteger;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 轮询调度
* 负载均衡
* copy from dubbo
* Created by darrenfu on 17-7-30.
*/
public class RoundRobinLoadBalancer extends AbstractLoadBalancer {
public static final String NAME = "roundrobin";
private final ConcurrentHashMap sequences = new ConcurrentHashMap<>();
@Override
protected ServerInstance doChoose(List instanceList, RestyCommand command) {
String key = command.getServiceName() + "." + command.getPath();
int length = instanceList.size(); // 总个数
int maxWeight = 0; // 最大权重
int minWeight = Integer.MAX_VALUE; // 最小权重
final LinkedHashMap invokerToWeightMap = new LinkedHashMap();
int weightSum = 0;
for (int i = 0; i < length; i++) {
int weight = getWeight(instanceList.get(i));
maxWeight = Math.max(maxWeight, weight); // 累计最大权重
minWeight = Math.min(minWeight, weight); // 累计最小权重
if (weight > 0) {
invokerToWeightMap.put(instanceList.get(i), new IntegerWrapper(weight));
weightSum += weight;
}
}
AtomicPositiveInteger sequence = sequences.get(key);
if (sequence == null) {
sequences.putIfAbsent(key, new AtomicPositiveInteger());
sequence = sequences.get(key);
}
int currentSequence = sequence.getAndIncrement();
if (maxWeight > 0 && minWeight < maxWeight) { // 权重不一样
int mod = currentSequence % weightSum;
for (int i = 0; i < maxWeight; i++) {
for (Map.Entry each : invokerToWeightMap.entrySet()) {
final ServerInstance instance = each.getKey();
final IntegerWrapper weight = each.getValue();
if (mod == 0 && weight.getValue() > 0) {
return instance;
}
if (weight.getValue() > 0) {
weight.decrement();
mod--;
}
}
}
}
// 取模轮循
return instanceList.get(currentSequence % length);
}
private static final class IntegerWrapper {
public IntegerWrapper(int value) {
this.value = value;
}
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public void decrement() {
this.value--;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy