平滑加权轮询算法
服务器权重分别是:
服务器: | A | B | C |
---|---|---|---|
权重: | 3 | 1 | 1 |
初始默认动态权重: | 0 | 0 | 0 |
动态权重(自己)=动态权重(自己)+静态权重(自己) | max(所有动态权重) | return | 动态权重(自己)=max(所有动态权重)-总静态权重(5) | |
---|---|---|---|---|
第一次 | 3,1,1 = (3,1,1 + 0,0,0) | 3 | A | -2,1,1 |
第二次 | 1,2,2 = (3,1,1 + -2,1,1) | 2 | B | 1,-3,2 |
第三次 | 4,-2,3 = (3,1,1 + 1,-3,2) | 4 | A | -1,-2,3 |
第四次 | 2,-1,4 = (3,1,1 + -1,-2,3) | 4 | C | 2,-1,-1 |
第五次 | 5,0,0 = (3,1,1 + 2,-1,-1) | 5 | A | 0,0,0 |
import java.util.HashMap;
import java.util.Map;
public class WeigthRoundRobin {
private static Map<String, Weight> weigths=new HashMap<>();
/**
* 服务器权重分别是:
* A B C
* 3 1 1
* 目标结果:A B A C A
*
* 动态权重默认:0
*
* 计算方式如下:
*
* 动态权重(自己)=动态权重(自己)+静态权重(自己) max(所有动态权重) return 动态权重(自己)=max(所有动态权重)-总静态权重(5)
* 3,1,1 = 3,1,1 + 0,0,0 3 A -2,1,1
* 1,2,2 = 3,1,1 + -2,1,1 2 B 1,-3,2
* 4,-2,3 = 3,1,1 + 1,-3,2 4 A -1,-2,3
* 2,-1,4 = 3,1,1 + -1,-2,3 4 C 2,-1,-1
* 5,0,0 = 3,1,1 + 2,-1,-1 5 A 0,0,0
*
* 3,1,1 = 3,1,1 + 0,0,0 3 A -2,1,1
* 1,2,2 = 3,1,1 + -2,1,1 2 B 1,-3,2
* 4,-2,3 = 3,1,1 + 1,-3,2 4 A -1,-2,3
* 2,-1,4 = 3,1,1 + -1,-2,3 4 C 2,-1,-1
* 5,0,0 = 3,1,1 + 2,-1,-1 5 A 0,0,0
*
*/
public static String getService() {
//初始化weigths
if(weigths.isEmpty()) {
ServerIps.WEIGHT_LIST.forEach((ip,weigth)->{
weigths.put(ip, new Weight(ip, weigth, 0));
});
}
int totalweigth=0;//总权重
for(Integer weigth: ServerIps.WEIGHT_LIST.values()) {
totalweigth+=weigth;
}
//当前权重=
for(Weight weight: weigths.values()) {
weight.setCurrentWeigth(weight.getCurrentWeigth()+weight.getWeigth());
}
Weight maxCurrentWeigth=null;
for(Weight weight: weigths.values()) {
if(maxCurrentWeigth==null||weight.getCurrentWeigth()>maxCurrentWeigth.getCurrentWeigth()) {
maxCurrentWeigth=weight;
}
}
maxCurrentWeigth.setCurrentWeigth(maxCurrentWeigth.getCurrentWeigth()-totalweigth);
return maxCurrentWeigth.getIp();
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(getService());
}
// int x=50;
// int n=2<<3;
// int y=x%n;
// int c=x&(n-1);
// System.out.println(y+" "+c);
}
}
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class ServerIps {
public static final List<String> LIST= Arrays.asList(
"192.168.0.1",
"192.168.0.2",
"192.168.0.3",
"192.168.0.4",
"192.168.0.5",
"192.168.0.6",
"192.168.0.7",
"192.168.0.8",
"192.168.0.9",
"192.168.0.10"
);
public static final Map<String, Integer> WEIGHT_LIST=new LinkedHashMap<>();
static {
WEIGHT_LIST.put("A", 3);
WEIGHT_LIST.put("B", 1);
WEIGHT_LIST.put("C", 1);
}
}
public class Weight {
private String ip;//ip
private Integer weigth;//静态权重(人为设置)
private Integer currentWeigth;//动态权重(0)
public Weight(String ip, Integer weigth, Integer currentWeigth) {
super();
this.ip = ip;
this.weigth = weigth;
this.currentWeigth = currentWeigth;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public Integer getWeigth() {
return weigth;
}
public void setWeigth(Integer weigth) {
this.weigth = weigth;
}
public Integer getCurrentWeigth() {
return currentWeigth;
}
public void setCurrentWeigth(Integer currentWeigth) {
this.currentWeigth = currentWeigth;
}
}
Hash算法
Hash环:利用红黑树特性实现Hash环算法
TreeMap 的 tailMap(n) 能获得大于等于hash值的一棵子红黑树
firstKey() 则返回整个红黑树的最小值
import java.util.SortedMap;
import java.util.TreeMap;
public class ConsistentHash {
private static TreeMap<Integer, String> virtualNodes = new TreeMap<>();
private static final int VIRTUAL_NODES = 10;
static {
for(String ip: ServerIps.LIST) {
for (int i = 0; i < VIRTUAL_NODES; i++) {
int hash = (ip+i).hashCode();
virtualNodes.put(hash, ip);
}
}
}
private static String getServer(String client) {
int hash = client.hashCode();
//能获得大于等于hash值的一棵子红黑树
SortedMap subMap = virtualNodes.tailMap(hash);
Integer firstKey = null;
if(subMap == null) {//如果未找到大于hash值的子树,则返回整个红黑树的最小值
firstKey = virtualNodes.firstKey();
} else {
firstKey = (Integer) subMap.firstKey();
}
return virtualNodes.get(firstKey);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int _ip = (int)(Math.random()*10);
System.out.println(getServer(ServerIps.LIST.get(_ip)+i));
}
}
}