权重轮询算法

阅读更多

 

相信熟悉过Nginx的都知道,Nginx其中有一个功能是负载均衡。

Nginx的负载均衡里可以配置一个服务器列表,如:

[html]  view plain  copy
 
  在CODE上查看代码片
  1. upstream detecotr_server {  
  2.             #ip_hash;    
  3.                 #这里指定多个源服务器,ip:端口,80端口的话可写可不写    
  4.                 server 192.168.154.1:8080 weight=1;# max_fails=2 fails_time=2;    
  5.                 server 192.168.154.2:8088 weight=2;# max_fail2=2 fails_time=2;    
  6.         }   

当负载均衡策略为加权轮询,如果的3个请求,则会有1个请求分发到192.168.154.1服务器上,2个请求分发到192.168.154.2服务器上。加权轮询的算法实现以下:

Java实现

 

[java]  view plain  copy
 
  在CODE上查看代码片
  1. public class WeightRoundRobin {  
  2.       
  3.     /**上次选择的服务器*/  
  4.     private int currentIndex = -1;  
  5.     /**当前调度的权值*/  
  6.     private int currentWeight = 0;  
  7.     /**最大权重*/  
  8.     private int maxWeight;  
  9.     /**权重的最大公约数*/  
  10.     private int gcdWeight;  
  11.     /**服务器数*/  
  12.     private int serverCount;  
  13.     private List servers = new ArrayList();  
  14.       
  15.     public int greaterCommonDivisor(int a, int b){  
  16.         BigInteger aBig = new BigInteger(String.valueOf(a));  
  17.         BigInteger bBig = new BigInteger(String.valueOf(b));  
  18.         return aBig.gcd(bBig).intValue();  
  19.     }  
  20.       
  21.     public int greatestCommonDivisor(List servers){  
  22.         int divisor = 0;  
  23.         for(int index = 0, len = servers.size(); index < len - 1; index++){  
  24.             if(index ==0){  
  25.                 divisor = greaterCommonDivisor(  
  26.                             servers.get(index).getWeight(), servers.get(index + 1).getWeight());  
  27.             }else{  
  28.                 divisor = greaterCommonDivisor(divisor, servers.get(index).getWeight());  
  29.             }  
  30.         }  
  31.         return divisor;  
  32.     }  
  33.       
  34.     public int greatestWeight(List servers){  
  35.         int weight = 0;  
  36.         for(Server server : servers){  
  37.             if(weight < server.getWeight()){  
  38.                 weight = server.getWeight();  
  39.             }  
  40.         }  
  41.         return weight;  
  42.     }  
  43.       
  44.     /** 
  45.     *  算法流程:  
  46.     *  假设有一组服务器 S = {S0, S1, …, Sn-1} 
  47.     *  有相应的权重,变量currentIndex表示上次选择的服务器 
  48.     *  权值currentWeight初始化为0,currentIndex初始化为-1 ,当第一次的时候返回 权值取最大的那个服务器, 
  49.     *  通过权重的不断递减 寻找 适合的服务器返回,直到轮询结束,权值返回为0  
  50.     */  
  51.     public Server getServer(){  
  52.         while(true){  
  53.             currentIndex = (currentIndex + 1) % serverCount;  
  54.             if(currentIndex == 0){  
  55.                 currentWeight = currentWeight - gcdWeight;  
  56.                 if(currentWeight <= 0){  
  57.                     currentWeight = maxWeight;  
  58.                     if(currentWeight == 0){  
  59.                         return null;  
  60.                     }  
  61.                 }  
  62.             }  
  63.             if(servers.get(currentIndex).getWeight() >= currentWeight){  
  64.                 return servers.get(currentIndex);  
  65.             }  
  66.         }  
  67.     }  
  68.       
  69.     public void init(){  
  70.         servers.add(new Server("192.168.1.101"1));  
  71.         servers.add(new Server("192.168.1.102"2));  
  72.         servers.add(new Server("192.168.1.103"3));  
  73.         servers.add(new Server("192.168.1.104"4));  
  74.         servers.add(new Server("192.168.1.105"5));  
  75.           
  76.         maxWeight = greatestWeight(servers);  
  77.         gcdWeight = greatestCommonDivisor(servers);  
  78.         serverCount = servers.size();  
  79.     }  
  80.       
  81.     public static void main(String[] args){  
  82.         WeightRoundRobin weightRoundRobin = new WeightRoundRobin();  
  83.         weightRoundRobin.init();  
  84.           
  85.         for(int i = 0; i < 15; i++){  
  86.             Server server = weightRoundRobin.getServer();  
  87.             System.out.println("server " + server.getIp() + " weight=" + server.getWeight());  
  88.         }  
  89.     }  
  90.   
  91. }  
  92.   
  93. class Server{  
  94.     private String ip;  
  95.       
  96.     private int weight;  
  97.       
  98.     public Server(String ip, int weight) {  
  99.         this.ip = ip;  
  100.         this.weight = weight;  
  101.     }  
  102.   
  103.     public String getIp() {  
  104.         return ip;  
  105.     }  
  106.   
  107.     public void setIp(String ip) {  
  108.         this.ip = ip;  
  109.     }  
  110.   
  111.     public int getWeight() {  
  112.         return weight;  
  113.     }  
  114.   
  115.     public void setWeight(int weight) {  
  116.         this.weight = weight;  
  117.     }  
  118.       
  119.     @Override  
  120.     public boolean equals(Object obj) {  
  121.         if(this == obj) return true;  
  122.           
  123.         if(obj instanceof Server){  
  124.             Server server = (Server)obj;  
  125.           
  126.             return getIp().equals(server.getIp());  
  127.         }  
  128.         return false;  
  129.     }  
  130.       
  131.     @Override  
  132.     public int hashCode() {  
  133.         return getIp().hashCode();  
  134.     }  
  135.       
  136. }  

结果:

server 192.168.1.105 weight=5
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.102 weight=2
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5
server 192.168.1.101 weight=1
server 192.168.1.102 weight=2
server 192.168.1.103 weight=3
server 192.168.1.104 weight=4
server 192.168.1.105 weight=5

 

 

你可能感兴趣的:(权重轮询算法)