权重轮询调度算法(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 }