轮询法是指:将请求按顺序轮流分配到服务器上,均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。
一、算法描述
假设有 N 台服务器 S = {S0, S1, S2, …, Sn},算法可以描述为:
1、从 S0 开始,依次调度 S0,S1, S2, …, Sn;
2、若所有服务器都已被调度过,则从头开始,循环调度;
假定现在有四台服务器,如下所示:
服务器地址 | 权重 |
---|---|
192.168.1.1 | 1 |
192.168.1.2 | 2 |
192.168.1.3 | 3 |
192.168.1.4 | 4 |
轮训算法调度结果如下:
服务器地址 | 序号 |
---|---|
192.168.1.1 | 1 |
192.168.1.2 | 2 |
192.168.1.3 | 3 |
192.168.1.4 | 4 |
192.168.1.1 | 5 |
192.168.1.2 | 6 |
192.168.1.3 | 7 |
192.168.1.4 | 8 |
轮训算法与服务器权重没有关系,每个服务器都会被有序地轮询访问。
在下面的代码示例中,以上面4台服务器为例进行演示。
二、java代码实现示例
package com.test.mvp.schedulealgothrim;
import com.google.common.collect.SortedMultiset;
import com.google.common.collect.TreeMultiset;
import java.io.Serializable;
import java.util.Map;
import java.util.TreeMap;
import java.util.ArrayList;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
class Server implements Serializable {
private static final long serialVersionUID = 7246747589293111189L;
private String server;
private String description;
public Server(String server, String description) {
this.server = server;
this.description = description;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getServer() {
return server;
}
public void setServer(String server) {
this.server = server;
}
}
class ServerManager {
public static Map<String, Server> serverMap = new TreeMap<>();
static {
serverMap.put("192.168.1.1", new Server("192.168.1.1", "第1台server"));
serverMap.put("192.168.1.2", new Server("192.168.1.2", "第2台server"));
serverMap.put("192.168.1.3", new Server("192.168.1.3", "第3台server"));
serverMap.put("192.168.1.4", new Server("192.168.1.4", "第4台server"));
}
}
public class RoundRobinTest {
private static AtomicInteger indexAtomic = new AtomicInteger(0);
public static String getServer() {
Set<String> serverSet = ServerManager.serverMap.keySet();
ArrayList<String> serverList = new ArrayList<>(serverSet);
if (indexAtomic.get() >= serverList.size()) {
indexAtomic.set(0);
}
return serverList.get(indexAtomic.getAndIncrement());
}
public static void main(String[] args) {
SortedMultiset<String> serverSet = TreeMultiset.create();
for (int i = 0; i < 100; i++) {
String server = getServer();
System.out.println(server + ", " + ServerManager.serverMap.get(server).getDescription());
serverSet.add(server, 1);
}
ServerManager.serverMap.forEach((key, value)->{
System.out.println(key + ", count:" + serverSet.count(key));
});
}
}
运行结果如下所示:
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, 第1台server
192.168.1.2, 第2台server
192.168.1.3, 第3台server
192.168.1.4, 第4台server
192.168.1.1, count:25
192.168.1.2, count:25
192.168.1.3, count:25
192.168.1.4, count:25
说明:
1、使用 AtomicInteger 进行轮询索引的增减,保证并发的安全性。
2、在多线程的情况下,若线程A修改 ServerManager.serverMap 的值,则线程B无法即时拿到线程A修改后的值,可能会导致请求错误,需要调用方进行容错处理。
本文地址:https://blog.csdn.net/chinawangfei/article/details/109581963
您可能感兴趣的文章:
- C++学习(十三)(C语言部分)之 练习
- sublime实现一键代码格式化
- 由于C++类库版本不同导致的OpenCV编译链接错误
- 番茄助手 最新 Visual Assist X 适应于VS2019 VS2017 VS2015 VS2013 亲测可用
- warning:parameter names (without types) in function declaration
- C++实现json字符串与map的转换
- Emulator: emulator: INFO: QtLogger.cpp:68: Critical: Uncaught ReferenceError: $ is not defined (qrc:
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!
网友评论