我正在尝试用Java编写一个简单的算法来选择哪个服务器需要执行一个操作.我想使用一种循环法,但每台服务器上都有一个重量.到目前为止,我编写了以下代码:
public static void main(String[] args) {
// Weight for each server
int x = 1;
int y = 3;
int counterx = 0;
int countery = 0;
for (int ii = 0; ii < 10; ii++) {
counterx++;
countery++;
if (counterx == x) {
System.out.println("Chosen x ");
counterx = 0;
}
if (countery == y) {
System.out.println("Chosen y ");
countery = 0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,给定两个服务器x和y,我已经存储了权重以分配给x和y变量中的每个服务器以及每个服务器的计数器.这似乎有效,但是如果服务器数量增加,代码将变得非常复杂.是否有任何util包可以帮助我根据权重因子确定要调用的服务器?
谢谢
实际上,类型实现NavigableMap是理想的,例如TreeMap.
你需要做一些事情:
这样,列表中服务器的排序无关紧要.这正是NavigableMap与ceilingEntry方法一起使用的内容.
例如:
public class ServerDetails {
int weight;
String address;
public Server(int weight, String address) {
this.weight = weight;
this.address = address;
}
public int getWeight(){return this.weight;}
public String getAddress(){return this.address;}
}
Run Code Online (Sandbox Code Playgroud)
然后使用以下内容定义服务器池:
public class ServerPool {
Random someRandGen = new Random();
TreeMap<Integer, ServerDetails> pool;
int totalWeight;
public void init(ArrayList<ServerDetails> servers) {
this.pool = new TreeMap<Integer, ServerDetails>();
// create the "weighted selection" list
totalWeight = 0;
for(ServerDetails s : servers) {
// associate each server with the sum of the weights so far
totalWeight += s.getWeight();
this.pool.put(totalWeight, s);
}
}
public ServerDetails getNext() {
int rnd = someRandGen.nextInt(this.totalWeight);
return pool.ceilingEntry(rnd).getValue();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以相应地为池定义添加/删除方法.与以下示例代码一起使用,每个选择的次数百分比为:
a: 11.1% b: 40.8% c: 19.6% d: 28.5%
码:
ArrayList<ServerDetails> servers = new ArrayList<ServerDetails>(){{
add(new ServerDetails(10, "a"));
add(new ServerDetails(40, "b"));
add(new ServerDetails(20, "c"));
add(new ServerDetails(30, "d"));
}};
ServerPool serverPool = new ServerPool();
serverPool.init(servers);
for (int i = 0; i < 10000; i++)
System.out.println(serverPool.getNext().getAddress());
Run Code Online (Sandbox Code Playgroud)