轮询顾名思义就是按照顺序进行轮流访问
实现算法如下:
public class RoundRobin {
//初始化全局变量,记录上次调用过得机器
public static int j;
static int[] servers = {1,2,3,4,5,6,7,8,9,10};
public static void main(String[] args) {
while(true){
try {
Thread.sleep(100);
System.out.println(getServer());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static String getServer(){
//初始化服务器
//上次调用机器+1取模
j = (j+1)%servers.length;
return "s"+j;
}
}
但是由于线上服务器由于配置或者非单一服务等原因,服务性能可能不一致,所以均等轮询策略满足不了需求,就有了加权轮询算法:
三台机器S[i] = {1,2,3},那么分配的权重可能是{2,4,6},那么访问算法如下:
import java.util.ArrayList;
import java.util.List;
public class WeightRoundRobin {
/**上次选择的服务器*/
private int currentIndex = -1;
/**当前调度的权值*/
private int currentWeight = 0;
/**最大权重*/
private int maxWeight;
/**权重的最大公约数*/
private int gcdWeight;
/**服务器数*/
private int serverCount;
private List<Server> servers = new ArrayList<Server>();
/*
* 得到两值的最大公约数
*/
public int greaterCommonDivisor(int a, int b){
if(a % b == 0){
return b;
}else{
return greaterCommonDivisor(b,a % b);
}
}
/*
* 得到list中所有权重的最大公约数,实际上是两两取最大公约数d,然后得到的d
* 与下一个权重取最大公约数,直至遍历完
*/
public int greatestCommonDivisor(List<Server> servers){
int divisor = 0;
for(int index = 0, len = servers.size(); index < len - 1; index++){
if(index ==0){
divisor = greaterCommonDivisor(
servers.get(index).getWeight(), servers.get(index + 1).getWeight());
}else{
divisor = greaterCommonDivisor(divisor, servers.get(index).getWeight());
}
}
return divisor;
}
/*
* 得到list中的最大的权重
*/
public int greatestWeight(List<Server> servers){
int weight = 0;
for(Server server : servers){
if(weight < server.getWeight()){
weight = server.getWeight();
}
}
return weight;
}
/**
* 算法流程:
* 假设有一组服务器 S = {S0, S1, …, Sn-1}
* 有相应的权重,变量currentIndex表示上次选择的服务器
* 权值currentWeight初始化为0,currentIndex初始化为-1 ,当第一次的时候返回 权值取最大的那个服务器,
* 通过权重的不断递减 寻找 适合的服务器返回
*/
public Server getServer(){
while(true){
currentIndex = (currentIndex + 1) % serverCount;
if(currentIndex == 0){
currentWeight = currentWeight - gcdWeight;
if(currentWeight <= 0){
currentWeight = maxWeight;
if(currentWeight == 0){
return null;
}
}
}
if(servers.get(currentIndex).getWeight() >= currentWeight){
return servers.get(currentIndex);
}
}
}
public void init(){
servers.add(new Server("192.168.191.1", 1));
servers.add(new Server("192.168.191.2", 2));
servers.add(new Server("192.168.191.4", 4));
servers.add(new Server("192.168.191.8", 8));
maxWeight = greatestWeight(servers);
gcdWeight = greatestCommonDivisor(servers);
serverCount = servers.size();
}
public static void main(String args[]){
WeightRoundRobin weightRoundRobin = new WeightRoundRobin();
weightRoundRobin.init();
for(int i = 0; i < 15; i++){
Server server = weightRoundRobin.getServer();
System.out.println("server " + server.getIp() + " weight=" + server.getWeight());
}
}
}
class Server{
private String ip;
private int weight;
public Server(String ip, int weight) {
this.ip = ip;
this.weight = weight;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}