權重輪詢調度算法(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 }