轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。轮询调度算法假设所有服务器的处理性能都相同,不关心每台服务器的当前连接数和响应速度。当请求服务间隔时间变化比较大时,轮询调度算法容易导致服务器间的负载不平衡。所以此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况。
轮询调度算法并没有考虑每台服务器的处理能力,在实际情况中,可能并不是这种情况。由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,我们根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。
package com.linux.util;
import java.util.ArrayList;
import java.util.List;
public class WeightRoundRobinCase {
/**上次选择的服务器*/
private int currentIndex = -1;
/**当前调度的权值*/
private int currentWeight = 0;
/**最大权重*/
private int maxWeight;
/**权重的最大公约数,公约数是这个数被多个数整除的,公约数之中最大的那个就是最大公约数
* 公约数与公倍数相反,就是既是A的约数同时也是B的约数的数,12和15的公约数有1,3,最大公约数就是3。
* 再举个例子,30和40,它们的公约数有1,2,5,10,最大公约数是10*/
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;
// System.out.println("上次选中的:"+currentIndex);
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.3", 3));
servers.add(new Server("192.168.191.4", 4));
maxWeight = greatestWeight(servers);
gcdWeight = greatestCommonDivisor(servers);
serverCount = servers.size();
System.out.println("初始化:"+maxWeight +" "+ gcdWeight +" "+ serverCount);
}
public static void main(String args[]){
WeightRoundRobinCase weightRoundRobin = new WeightRoundRobinCase();
weightRoundRobin.init();
for(int i = 0; i < 10; 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;
}
}