import java.util.Arrays;
import java.util.HashMap;
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 HashMap<String,Integer>();
static
{
WEIGHT_LIST.put("192.168.0.1",1);
WEIGHT_LIST.put("192.168.0.2",8);
WEIGHT_LIST.put("192.168.0.3",3);
WEIGHT_LIST.put("192.168.0.4",6);
WEIGHT_LIST.put("192.168.0.5",5);
WEIGHT_LIST.put("192.168.0.6",5);
WEIGHT_LIST.put("192.168.0.7",4);
WEIGHT_LIST.put("192.168.0.8",7);
WEIGHT_LIST.put("192.168.0.9",2);
WEIGHT_LIST.put("192.168.0.10",9);
}
}
随机
import java.util.Random;
public class RandomLoadBalance {
public static String getServer()
{
Random random = new Random();
int randomPos =random.nextInt(ServerIPs.LIST.size());
return ServerIPs.LIST.get(randomPos);
}
public static void main(String[] args) {
for(int i=0;i<10;i++)
{
System.out.println(getServer());
}
}
}
加权随机 (扩容)
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class WeightRandom {
public static String getServer()
{
List<String>newServer = new ArrayList<String>();
Random random = new Random();
for (Map.Entry<String, Integer> map:ServerIPs.WEIGHT_LIST.entrySet())
{
String ip = map.getKey();
int weight = map.getValue();
for(int i=0;i<weight;i++)
{
newServer.add(ip);
}
}
int pos = random.nextInt(newServer.size());
return newServer.get(pos);
}
public static void main(String[] args) {
for (int i=0;i<10;i++)
{
String str = getServer();
System.out.println(String.format("ip: %s, weight: %d", str,ServerIPs.WEIGHT_LIST.get(str)));
}
}
}
加权随机 (区间)
import java.util.Map;
import java.util.Random;
public class WeightRandomV2 {
private int all = 0;
public static String getServer2()
{
Random random = new Random();
int totalWeight = 0;
for(Map.Entry<String,Integer>entry:ServerIPs.WEIGHT_LIST.entrySet())
{
totalWeight += entry.getValue();
}
int pos = random.nextInt(totalWeight);
String res = "";
for(Map.Entry<String,Integer>entry:ServerIPs.WEIGHT_LIST.entrySet())
{
int weight = entry.getValue();
if (pos<weight)
{
res = entry.getKey();
break;
}
pos -= weight;
}
return res;
}
public static void main(String[] args) {
int[]arr = new int[10];
for (int i=0;i<20;i++)
{
String str = getServer2();
int weight = ServerIPs.WEIGHT_LIST.get(str);
arr[weight]++;
System.out.println(String.format("ip: %s, weight: %d", str,ServerIPs.WEIGHT_LIST.get(str)));
}
for (int i=0;i<10;i++)
{
System.out.println(String.format("weight: %d, fre: %f", i, arr[i] / 20.0));
}
}
}
轮询
public class RoundRobin {
private static Integer pos = 0;
public static String getServer()
{
String ip = "";
synchronized(pos)
{
ip = ServerIPs.LIST.get(pos);
pos++;
if (pos==ServerIPs.LIST.size())
{
pos = 0;
}
}
return ip;
}
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
System.out.println(getServer());
}
}
}
加权轮询 (取余,区间)
import java.util.Map;
import java.util.Random;
public class RoundRobinWeight {
private static Integer pos = 0;
public static String getServer()
{
int totalWeight = 0;
for (Map.Entry<String,Integer>entry:ServerIPs.WEIGHT_LIST.entrySet())
{
totalWeight += entry.getValue();
}
Random random = new Random();
String ip = "";
synchronized (pos)
{
int offset = pos%totalWeight;
for (Map.Entry<String,Integer>entry:ServerIPs.WEIGHT_LIST.entrySet())
{
int weight = entry.getValue();
if (offset<=weight)
{
ip = entry.getKey();
break;
}
offset = offset - weight;
}
pos++;
}
return ip;
}
public static void main(String[] args) {
int[]arr = new int[10];
for (int i=0;i<20;i++)
{
String str = getServer();
int weight = ServerIPs.WEIGHT_LIST.get(str);
arr[weight]++;
System.out.println(String.format("ip: %s, weight: %d", str,ServerIPs.WEIGHT_LIST.get(str)));
}
for (int i=0;i<10;i++)
{
System.out.println(String.format("weight: %d, fre: %f", i, arr[i] / 20.0));
}
}
}
加权轮询,平滑
import java.util.ArrayList;
import java.util.List;
class Weight{
private String ip;
private Integer weight;
private Integer currentWeight;
public Weight(String ip, Integer weight, Integer currentWeight) {
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;
}
}
public class RoundRobinWeight2 {
int totalWeight = ServerIPs.WEIGHT_LIST.values().stream().reduce(0,Integer::sum);
List<Weight>list = new ArrayList<>();
public String getServer()
{
if (list.isEmpty())
{
ServerIPs.WEIGHT_LIST.forEach((key,value)->list.add(new Weight(key,value,value)));
}
Weight maxCurrent = null;
for (Weight weight:list)
{
if (maxCurrent==null || maxCurrent.getCurrentWeight()<weight.getCurrentWeight())
{
maxCurrent = weight;
}
}
maxCurrent.setCurrentWeight(maxCurrent.getCurrentWeight() - totalWeight);
for (Weight weight:list)
{
weight.setCurrentWeight(weight.getCurrentWeight() + weight.getWeight());
}
return maxCurrent.getIp();
}
public static void main(String[] args) {
RoundRobinWeight2 r2 = new RoundRobinWeight2();
System.out.println(String.format("weight: %d",r2.totalWeight));
int[]arr = new int[10];
for (int i=0;i<20;i++)
{
String str = r2.getServer();
int weight = ServerIPs.WEIGHT_LIST.get(str);
arr[weight]++;
System.out.println(String.format("ip: %s, weight: %d", str,ServerIPs.WEIGHT_LIST.get(str)));
}
for (int i=0;i<10;i++)
{
System.out.println(String.format("weight: %d, fre: %f", i, arr[i] / 20.0));
}
}
}
一致性哈希
import java.util.SortedMap;
import java.util.TreeMap;
class Tools{
private int getHash(String str) {
final int p = 16777619;
int hash = (int) 2166136261L;
for (int i = 0; i < str.length(); i++)
hash = (hash ^ str.charAt(i)) * p;
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
if (hash < 0)
hash = Math.abs(hash);
return hash;
}
private TreeMap<Integer,String>virtualMap = new TreeMap<>();
private final int VIRTUAL_NODE = 160;
public void addNode()
{
for (String Ip: ServerIPs.LIST)
{
for (int i=0;i<VIRTUAL_NODE;i++)
{
int hash = getHash(Ip + i);
virtualMap.put(hash,Ip);
}
}
}
public String getServer(String client)
{
int hash = getHash(client);
SortedMap<Integer,String> subMap = virtualMap.tailMap(hash);
Integer nodeIndex = subMap.firstKey();
if (nodeIndex==null)
{
nodeIndex = virtualMap.firstKey();
}
return virtualMap.get(nodeIndex);
}
}
public class ConsistentHash {
public static void main(String[] args) {
Tools tools = new Tools();
tools.addNode();
int[]arr = new int[10];
for (int i=0;i<20;i++)
{
String str = tools.getServer("client" + i);
int weight = ServerIPs.WEIGHT_LIST.get(str);
arr[weight]++;
System.out.println(String.format("ip: %s, weight: %d", str,ServerIPs.WEIGHT_LIST.get(str)));
}
for (int i=0;i<10;i++)
{
System.out.println(String.format("weight: %d, fre: %f", i, arr[i] / 10.0));
}
}
}