java 带权重轮询算法
import java.util.ArrayList;
import java.util.List;
/**
* 一个实现加权轮询算法的类。
*/
class WeightedRoundRobin {
// 保存权重的服务器节点列表
private volatile List<ServerNode> serverNodes = new ArrayList<>();
/**
* 添加一个服务器节点到列表中。
*
* @param serverNode 要添加的服务器节点
*/
public void addServer(ServerNode serverNode) {
serverNodes.add(serverNode);
}
/**
* 根据当前权重轮询选择一个服务器节点。
*
* @return 返回被选中的服务器节点
*/
public ServerNode getNextServer() {
int totalWeight = 0; // 记录所有节点的总权重
ServerNode maxServerNode = null; // 用于保存当前权重最大的节点
if (null == serverNodes || serverNodes.isEmpty()) {
return maxServerNode;
}
int maxWeight = 0; // 记录当前发现的最大权重
// 遍历所有服务器节点,更新它们的当前权重,并找出当前权重最大的节点
for (int i = 0; i < serverNodes.size(); i++) {
ServerNode n = serverNodes.get(i);
totalWeight += n.getWeight();
// 更新节点的当前权重
n.setCurrentWeight(n.getCurrentWeight() + n.getWeight());
// 比较并保存当前权重最大的节点
if (maxServerNode == null || maxWeight < n.getCurrentWeight()) {
maxServerNode = n;
maxWeight = n.getCurrentWeight();
}
}
// 被选中的节点权重减掉总权重,为下一次选择做准备
maxServerNode.setCurrentWeight(maxServerNode.getCurrentWeight() - totalWeight);
return maxServerNode;
}
/**
* 适合单个请求
*
* @return
*/
public ServerNode random() {
if (null == serverNodes || serverNodes.isEmpty()) {
return null;
}
ArrayList<ServerNode> data = new ArrayList<>();
for (int i = 0; i < serverNodes.size(); i++) {
int weight = serverNodes.get(i).getWeight();
for (int j = 0; j < weight; j++) {
data.add(serverNodes.get(i));
}
}
if (data.isEmpty()) {
return null;
}
int index = new Random().nextInt(data.size());
return data.get(index);
}
}
/**
* 表示一个服务器节点的类。
*/
class ServerNode {
// 初始权重,不会改变
private final int weight;
// 服务器名称
private final String serverName;
// 当前权重,可变
private int currentWeight;
/**
* 构造一个服务器节点。
*
* @param serverName 服务器名称
* @param weight 初始权重
*/
public ServerNode(String serverName, int weight) {
this.weight = weight;
this.serverName = serverName;
this.currentWeight = weight;
}
// 以下是一些getter和setter方法,用于访问类的属性
public int getCurrentWeight() {
return currentWeight;
}
public void setCurrentWeight(int currentWeight) {
this.currentWeight = currentWeight;
}
public int getWeight() {
return weight;
}
public String getServerName() {
return serverName;
}
}
/**
* 测试类,用于演示加权轮询算法的使用。
*/
class Test {
public static void main(String[] args) {
// 创建并配置三个服务器节点
ServerNode serverA = new ServerNode("serverA", 4);
ServerNode serverB = new ServerNode("serverB", 3);
ServerNode serverC = new ServerNode("serverC", 2);
// 创建加权轮询对象,并添加服务器节点
WeightedRoundRobin weightedRoundRobin = new WeightedRoundRobin();
weightedRoundRobin.addServer(serverA);
weightedRoundRobin.addServer(serverB);
weightedRoundRobin.addServer(serverC);
// 进行9次选择,演示加权轮询算法的工作过程
for (int i = 0; i < 9; i++) {
ServerNode i1 = weightedRoundRobin.getNextServer();
System.out.println(i1.getServerName());
}
}
}
单次随机使用random方法