權重輪詢調度算法(WeightedRound-RobinScheduling)-Java實現
----參考Nginx中負載均衡算法實現
與上一遍博客 http://www.cnblogs.com/huligong1234/p/3819979.html 中實現方式不同,
這里主要參考這篇文章的實現: Nginx 負載均衡-加權輪詢策略剖析 http://www.cnblogs.com/dyllove98/archive/2013/07/13/3188450.html,
與上一遍中實現比起來,效果比較好,權重比較低的服務器,也比較容易背獲取到,但請求數量比較大的時候,兩個實現方式中,每個服務器分擔的請求數基本無差別,區別主要是順序上。
本篇文章也加上了動態添加服務器,和動態down掉服務器的演示實例。 由於研究本算法的目的是在其他方面的應用,故涉及服務器請求超時時間等因素,並未考慮。
1 import java.util.ArrayList; 2 import java.util.Date; 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 List<Server> serverList; //服務器集合 15 16 public Server GetBestServer() { 17 Server server = null; 18 Server best = null; 19 int total = 0; 20 for(int i=0,len=serverList.size();i<len;i++){ 21 //當前服務器對象 22 server = serverList.get(i); 23 24 //當前服務器已宕機,排除 25 if(server.down){ 26 continue; 27 } 28 29 server.currentWeight += server.effectiveWeight; 30 total += server.effectiveWeight; 31 32 if(server.effectiveWeight < server.weight){ 33 server.effectiveWeight++; 34 } 35 36 if(best == null || server.currentWeight>best.currentWeight){ 37 best = server; 38 } 39 40 } 41 42 if (best == null) { 43 return null; 44 } 45 46 best.currentWeight -= total; 47 best.checkedDate = new Date(); 48 return best; 49 } 50 51 52 53 class Server { 54 public String ip; 55 public int weight; 56 public int effectiveWeight; 57 public int currentWeight; 58 public boolean down = false; 59 public Date checkedDate; 60 public Server(String ip, int weight) { 61 super(); 62 this.ip = ip; 63 this.weight = weight; 64 this.effectiveWeight = this.weight; 65 this.currentWeight = 0; 66 if(this.weight < 0){ 67 this.down = true; 68 }else{ 69 this.down = false; 70 } 71 } 72 public String getIp() { 73 return ip; 74 } 75 public void setIp(String ip) { 76 this.ip = ip; 77 } 78 public int getWeight() { 79 return weight; 80 } 81 public void setWeight(int weight) { 82 this.weight = weight; 83 } 84 public int getEffectiveWeight() { 85 return effectiveWeight; 86 } 87 public void setEffectiveWeight(int effectiveWeight) { 88 this.effectiveWeight = effectiveWeight; 89 } 90 public int getCurrentWeight() { 91 return currentWeight; 92 } 93 public void setCurrentWeight(int currentWeight) { 94 this.currentWeight = currentWeight; 95 } 96 public boolean isDown() { 97 return down; 98 } 99 public void setDown(boolean down) { 100 this.down = down; 101 } 102 public Date getCheckedDate() { 103 return checkedDate; 104 } 105 public void setCheckedDate(Date checkedDate) { 106 this.checkedDate = checkedDate; 107 } 108 109 } 110 111 112 public void init() { 113 Server s1 = new Server("192.168.0.100", 3);//3 114 Server s2 = new Server("192.168.0.101", 2);//2 115 Server s3 = new Server("192.168.0.102", 6);//6 116 Server s4 = new Server("192.168.0.103", 4);//4 117 Server s5 = new Server("192.168.0.104", 1);//1 118 Server s6 = new Server("192.168.0.105", 0);//0 119 Server s7 = new Server("192.168.0.106", 0);//0 120 Server s8 = new Server("192.168.0.107", 0);//0 121 Server s9 = new Server("192.168.0.108", 0);//0 122 serverList = new ArrayList<Server>(); 123 serverList.add(s1); 124 serverList.add(s2); 125 serverList.add(s3); 126 serverList.add(s4); 127 serverList.add(s5); 128 serverList.add(s6); 129 serverList.add(s7); 130 serverList.add(s8); 131 serverList.add(s9); 132 } 133 134 public void add(int i) { 135 Server s = new Server("192.168.0.1"+i, i-15); 136 serverList.add(s); 137 } 138 139 public Server getServer(int i) { 140 if(i<serverList.size()){ 141 return serverList.get(i); 142 } 143 return null; 144 } 145 146 147 public static void main(String[] args) { 148 WeightedRoundRobinScheduling obj = new WeightedRoundRobinScheduling(); 149 obj.init(); 150 151 Map<String,Integer> countResult = new HashMap<String,Integer>(); 152 153 for (int i = 0; i < 100; i++) { 154 Server s = obj.GetBestServer(); 155 String log = "ip:"+s.ip+";weight:"+s.weight; 156 if(countResult.containsKey(log)){ 157 countResult.put(log,countResult.get(log)+1); 158 }else{ 159 countResult.put(log,1); 160 } 161 System.out.println(log); 162 163 //動態添加服務器 164 if(i==20 || i==22){ 165 obj.add(i); 166 } 167 168 //動態停止服務器 169 if(i==30){ 170 obj.getServer(2).setDown(true); 171 obj.getServer(3).setDown(true); 172 } 173 } 174 175 for(Entry<String, Integer> map : countResult.entrySet()){ 176 System.out.println("服務器 "+map.getKey()+" 請求次數: "+map.getValue()); 177 } 178 } 179 180 }