标签:oid 模仿 均衡 table result 顺序 code i++ tip
主要思想是服务器一个接一个的服务
public class RoundRobin {
private static Integer pos = 0;
public static String getServer() {
if(pos >= ServerIps.LIST.size()) {
pos = 0;
}
String ip = ServerIps.LIST.get(pos);
pos++;
return ip;
}
public static void main(String[] args) {
for(int i = 0; i < 20; i++) {
System.out.println(getServer());
}
}
}
考虑权重的时候
其中A、B、C分别代表3个IP地址,权重分别为5、3、2 A: 5 B: 3 C: 2
映射到坐标轴为
0-----5---8--10
offset的取值再不是一个随机数,而是0,1,2,3,4,5,6,7,8,9
1 ——> A
2 ——> A
...
6 ——> B
...
代码实现
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ServerIps {
public static final Map<String, Integer> WEIGHT_MAP = new LinkedHashMap<>();
static {
WEIGHT_MAP.put("192.168.0.1", 2);
WEIGHT_MAP.put("192.168.0.2", 8);
WEIGHT_MAP.put("192.168.0.3", 1);
WEIGHT_MAP.put("192.168.0.4", 9);
WEIGHT_MAP.put("192.168.0.5", 4);
WEIGHT_MAP.put("192.168.0.6", 6);
}
}
注意其中采用的是LinkedHashMap,这样可以保证输出的顺序和输入的顺序一致
public class RequestId {
public static Integer num = 0;
public static Integer getAndIncrement() {
return num++;
}
}
上面代码模仿的是客户的ID号,根据客户的ID号来控制服务器的轮询。
public class RoundRobin2 {
public static String getServer() {
int totalWeight = 0;
for (Integer weight: ServerIps.WEIGHT_MAP.values()) {
totalWeight += weight;
}
int requestId = RequestId.getAndIncrement();
int offset = requestId % totalWeight;
for(String ip: ServerIps.WEIGHT_MAP.keySet()) {
Integer weight = ServerIps.WEIGHT_MAP.get(ip);
if (offset < weight) {
return ip;
}
offset -= weight;
}
return null;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(getServer());
}
}
}
Nginx默认采用这种算法
A: 5
B: 1
C: 1
这样的话,优化1中的访问顺序为AAAAABC,这样的话对服务器A的压力比较大
如果按照离散的话,就不会有这样的问题,如下面这种顺序
AABACAA
这样不仅能使服务比较分散,也能保证权重,还能达到轮询的目的
具体过程如下:
ip
weight: 静态,5,1,1 currentWeight:动态
currentWeight: 0,0,0
currentWeight+=weight | max(currentWeight) | result | max(currentWeight)-=sum(weight)7 |
---|---|---|---|
5,1,1 | 5 | A | -2,1,1 |
3,2,2 | 3 | A | -4,2,2 |
1,3,3 | 3 | B | 1,-4,3 |
6,-3,4 | 6 | A | -1,-3,4 |
4,-2,5 | 5 | C | 4,-2,-2 |
9,-1,-1 | 9 | A | 2,-1,-1 |
7,0,0 | 7 | A | 0,0,0 |
5,1,1 | ... | ... | ... |
代码实现
public class Weight {
private String ip;
private Integer weight;
private Integer currentWeight;
public Weight(String ip, Integer weight, Integer currentWeight) {
super();
this.ip = ip;
this.weight = weight;
this.currentWeight = currentWeight;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public Integer getCurrentWeight() {
return currentWeight;
}
public void setCurrentWeight(Integer currentWeight) {
this.currentWeight = currentWeight;
}
}
=============================
import java.util.LinkedHashMap;
import java.util.Map;
public class WeightRoundRobin {
private static Map<String, Weight> weightMap = new LinkedHashMap<>();
public static String getServer() {
if(weightMap.isEmpty()) {
for(String ip: ServerIps.WEIGHT_MAP.keySet()) {
Integer weight = ServerIps.WEIGHT_MAP.get(ip);
weightMap.put(ip, new Weight(ip, weight, 0));
}
}
// currentWeight += weight
for(Weight weight: weightMap.values()) {
weight.setCurrentWeight(weight.getCurrentWeight() + weight.getWeight());
}
Weight maxCurrentWeight = null;
for (Weight weight: weightMap.values()) {
if (maxCurrentWeight == null || weight.getCurrentWeight() > maxCurrentWeight.getCurrentWeight()) {
maxCurrentWeight = weight;
}
}
// max(currentWeight) -= sum(weight)
int totalWeight = 0;
for (Integer weight: ServerIps.WEIGHT_MAP.values()) {
totalWeight += weight;
}
maxCurrentWeight.setCurrentWeight(maxCurrentWeight.getCurrentWeight() - totalWeight);
//result
return maxCurrentWeight.getIp();
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(getServer());
}
}
}
标签:oid 模仿 均衡 table result 顺序 code i++ tip
原文地址:https://www.cnblogs.com/Stephanie-boke/p/12289736.html