輪詢算法


在多台機器實現負載均衡的時候,經常用到輪詢調度算法(Round-Robin Scheduling)。

輪詢調度算法就是以循環的方式依次將請求調度不同的服務器,即每次調度執行i = (i + 1) mod n,並選出第i台服務器。

算法的優點是其簡潔性,它無需記錄當前所有連接的狀態,所以它是一種無狀態調度。

 

1、算法流程:
假設有一組服務器 S = {S0, S1, …, Sn-1} ,有相應的權重,變量i表示上次選擇的服務器,權值cw初始化為0,i初始化為-1 ,當第一次的時候取權值取最大的那個服務器,通過權重的不斷遞減,尋找適合的服務器返回,直到輪詢結束,權值返回為0

 1 import java.math.BigInteger;
  2 import java.util.ArrayList;
  3 import java.util.HashMap;
  4 import java.util.List;
  5 import java.util.Map;
  6 import java.util.Map.Entry;
  7 
  8 /**
  9  * 權重輪詢調度算法(WeightedRound-RobinScheduling)-Java實現
 10  * @author huligong
 11  * */
 12 public class WeightedRoundRobinScheduling {
 13 
 14     private int currentIndex = -1;// 上一次選擇的服務器
 15     private int currentWeight = 0;// 當前調度的權值
 16     private int maxWeight = 0; // 最大權重
 17     private int gcdWeight = 0; //所有服務器權重的最大公約數
 18     private int serverCount = 0; //服務器數量
 19     private List<Server> serverList; //服務器集合
 20 
 21     /**
 22      * 返回最大公約數
 23      * @param a
 24      * @param b
 25      * @return
 26      */
 27     private static int gcd(int a, int b) {
 28         BigInteger b1 = new BigInteger(String.valueOf(a));
 29         BigInteger b2 = new BigInteger(String.valueOf(b));
 30         BigInteger gcd = b1.gcd(b2);
 31         return gcd.intValue();
 32     }
 33     
 34      
 35     /**
 36      * 返回所有服務器權重的最大公約數
 37      * @param serverList
 38      * @return
 39      */
 40     private static int getGCDForServers(List<Server> serverList ) {
 41         int w = 0;
 42         for (int i = 0, len = serverList.size(); i < len - 1; i++) {
 43             if (w == 0) {
 44                 w = gcd(serverList.get(i).weight, serverList.get(i + 1).weight);
 45             } else {
 46                 w = gcd(w, serverList.get(i + 1).weight);
 47             }
 48         }
 49         return w;
 50     }
 51     
 52 
 53     /**
 54      * 返回所有服務器中的最大權重
 55      * @param serverList
 56      * @return
 57      */
 58     public static int getMaxWeightForServers(List<Server> serverList) {
 59         int w = 0;
 60         for (int i = 0, len = serverList.size(); i < len - 1; i++) {
 61             if (w == 0) {
 62                 w = Math.max(serverList.get(i).weight, serverList.get(i + 1).weight);
 63             } else {
 64                 w = Math.max(w, serverList.get(i + 1).weight);
 65             }
 66         }
 67         return w;
 68     }
 69     
 70     /**
 71      *  算法流程: 
 72      *  假設有一組服務器 S = {S0, S1, …, Sn-1}
 73      *  有相應的權重,變量currentIndex表示上次選擇的服務器
 74      *  權值currentWeight初始化為0,currentIndex初始化為-1 ,當第一次的時候返回 權值取最大的那個服務器,
 75      *  通過權重的不斷遞減 尋找 適合的服務器返回,直到輪詢結束,權值返回為0 
 76      */
 77     public Server GetServer() {
 78         while (true) {
 79             currentIndex = (currentIndex + 1) % serverCount;
 80             if (currentIndex == 0) {
 81                 currentWeight = currentWeight - gcdWeight;
 82                 if (currentWeight <= 0) {
 83                     currentWeight = maxWeight;
 84                     if (currentWeight == 0)
 85                         return null;
 86                 }
 87             }
 88             if (serverList.get(currentIndex).weight >= currentWeight) {
 89                 return serverList.get(currentIndex);
 90             }
 91         }
 92     }
 93 
 94 
 95     class Server {
 96         public String ip;
 97         public int weight;
 98         public Server(String ip, int weight) {
 99             super();
100             this.ip = ip;
101             this.weight = weight;
102         }
103         public String getIp() {
104             return ip;
105         }
106         public void setIp(String ip) {
107             this.ip = ip;
108         }
109         public int getWeight() {
110             return weight;
111         }
112         public void setWeight(int weight) {
113             this.weight = weight;
114         }
115     }
116     
117 
118     public void init() {
119         Server s1 = new Server("192.168.0.100", 3);//3
120         Server s2 = new Server("192.168.0.101", 2);//2
121         Server s3 = new Server("192.168.0.102", 6);//6
122         Server s4 = new Server("192.168.0.103", 4);//4
123         Server s5 = new Server("192.168.0.104", 1);//1
124         serverList = new ArrayList<Server>();
125         serverList.add(s1);
126         serverList.add(s2);
127         serverList.add(s3);
128         serverList.add(s4);
129         serverList.add(s5);
130         
131         currentIndex = -1;
132         currentWeight = 0;
133         serverCount = serverList.size();
134         maxWeight = getMaxWeightForServers(serverList);
135         gcdWeight = getGCDForServers(serverList);
136     }
137     
138     
139     public static void main(String[] args) {
140         WeightedRoundRobinScheduling obj = new WeightedRoundRobinScheduling();
141         obj.init();
142         
143         Map<String,Integer> countResult = new HashMap<String,Integer>();
144         
145         for (int i = 0; i < 100; i++) {
146             Server s = obj.GetServer();
147             String log = "ip:"+s.ip+";weight:"+s.weight;
148             if(countResult.containsKey(log)){
149                 countResult.put(log,countResult.get(log)+1);
150             }else{
151                 countResult.put(log,1);
152             }
153             System.out.println(log);
154         }
155         
156         for(Entry<String, Integer> map : countResult.entrySet()){
157             System.out.println("服務器 "+map.getKey()+" 請求次數: "+map.getValue());
158         }
159     }
160 
161 }

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM