权重轮询调度算法(WeightedRound-RobinScheduling)-Java实现2
权重轮询调度算法(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 }