缺点:所有服务器的访问概率都是相同的。
package com.example.demo.core.random;
import JAVA.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* 负载均衡算法
* 完全随机算法
*/
public class RandomServer {
public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");
static Random random = new Random();
public static String getServer() {
int number = random.nextInt(list.size());
return list.get(number);
}
public static void main(String[] args) {
for(int i = 0; i < 15; i++) {
System.out.println(getServer());
}
}
}
场景:有的服务器性能高,可以让随机到此服务器的可能性增大
缺点:权重低的服务器可能很长一段时间都访问不到3
package com.example.demo.core.random;
import java.util.*;
/**
* 负载均衡算法
*
* 如果某一台服务器性能比较高,设置访问的权重高一点
*
* 加权随机算法
*/
public class WeightRandomServer {
public static Map<String,Integer> map = new HashMap<>();
static {
map.put("10.180.11.126:8888",2);
map.put("10.180.11.128:8888",7);
map.put("10.180.11.130:8888",1);
}
static Random random = new Random();
/**
* 当权重设置过大时,list容易被撑爆
* @return
*/
public static String getServer() {
List<String> list = new ArrayList<>();
for(Map.Entry<String,Integer> entry: map.entrySet()) {
//根据权重,决定向list中添加几次
for(int i = 0; i < entry.getValue(); i++) {
list.add(entry.getKey());
}
}
//list的大小
int weight = map.values().stream().mapToInt(p -> p).sum();
int number = random.nextInt(weight);
return list.get(number);
}
/**
* 优化后
* @return
*/
public static String getServer1() {
//计算总权值
int weight = map.values().stream().mapToInt(p -> p).sum();
//随机一个随机数
int index = random.nextInt(weight);
//遍历 服务 map
for(Map.Entry<String,Integer> entry : map.entrySet()) {
//如果权重大于 索引
if(entry.getValue() >= index) {
// 返回这个服务
return entry.getKey();
}
//否则,索引 = 当前索引 - 当前服务的权重
index = index - entry.getValue();
}
return "";
}
public static void main(String[] args) {
for(int i = 0; i < 15; i++) {
//System.out.println(getServer());
System.out.println(getServer1());
}
}
}
缺点:从头到尾轮询一遍,不能根据服务器性能设置权重
package com.example.demo.core.poll;
import java.util.Arrays;
import java.util.List;
/**
* 完全轮询算法
*/
public class PollServer {
public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");
static int index;
public static String getServer() {
if(index == list.size()) {
index = 0;
}
return list.get(index++);
}
public static void main(String[] args) {
for(int i = 0; i < 15; i++) {
System.out.println(getServer());
}
}
}
有点:可以根据服务器性能设置访问权重
缺点:可能某个服务器权重大,长时间执行,遇到耗时大的请求,压力会很大
package com.example.demo.core.poll;
import java.util.HashMap;
import java.util.Map;
/**
* 加权轮询算法
* 实际中可能遇到某个服务器压力较大,长时间执行。
*/
public class WeightPollServer {
public static Map<String,Integer> map = new HashMap<>();
static {
map.put("10.180.11.126:8888",2);
map.put("10.180.11.128:8888",7);
map.put("10.180.11.130:8888",5);
}
static int index;
public static String getServer() {
int weight = map.values().stream().mapToInt( p -> p).sum();
int number = (index++) % weight;
for(Map.Entry<String,Integer> entry : map.entrySet()) {
if(entry.getValue() >= number) {
return entry.getKey();
}
number = number - entry.getValue();
}
return "";
}
public static void main(String[] args) {
for(int i = 0; i < 15; i++) {
System.out.println(getServer());
}
}
}
优点:根据权重分配服务,同时又保证权重低的服务可以被访问到
缺点:集群环境下,同一个用户访问无法分流到固定一台机器
package com.example.demo.core.smooth;
/**
* 平滑加权
*/
public class SmoothWeight {
private int weight;
private int currentWeight;
private String address;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getCurrentWeight() {
return currentWeight;
}
public void setCurrentWeight(int currentWeight) {
this.currentWeight = currentWeight;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public SmoothWeight(int weight, int currentWeight, String address) {
this.weight = weight;
this.currentWeight = currentWeight;
this.address = address;
}
}
package com.example.demo.core.smooth;
import java.util.HashMap;
import java.util.Map;
/**
* 平滑加权轮询算法
*/
public class SmoothWeightPollServer {
public static Map<String,SmoothWeight> map = new HashMap<>();
static {
map.put("10.180.11.126:8888",new SmoothWeight(5,5,"10.180.11.126:8888"));
map.put("10.180.11.128:8888",new SmoothWeight(2,2,"10.180.11.128:8888"));
map.put("10.180.11.130:8888",new SmoothWeight(4,4,"10.180.11.130:8888"));
}
public static String getServer() {
SmoothWeight maxSmoothWeight = null;
int weight = map.values().stream().mapToInt(SmoothWeight :: getWeight).sum();
for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) {
SmoothWeight currentSmoothWeight = entry.getValue();
if(maxSmoothWeight == null || currentSmoothWeight.getCurrentWeight() > maxSmoothWeight.getCurrentWeight()) {
maxSmoothWeight = currentSmoothWeight;
}
}
assert maxSmoothWeight != null;
maxSmoothWeight.setCurrentWeight(maxSmoothWeight.getCurrentWeight() - weight);
for(Map.Entry<String,SmoothWeight> entry : map.entrySet()) {
SmoothWeight currentSmoothWeight = entry.getValue();
currentSmoothWeight.setCurrentWeight(currentSmoothWeight.getCurrentWeight() + currentSmoothWeight.getWeight());
}
return maxSmoothWeight.getAddress();
}
public static void main(String[] args) {
for(int i = 0; i < 15; i++) {
System.out.println(getServer());
}
}
}
package com.example.demo.core.hash;
import java.util.Arrays;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* hash负载算法
* 在一个集群环境下,让同一个用户的访问,分流到固定的一台机器上
*/
public class HashServer {
public static List<String> list = Arrays.asList("10.180.11.126:8888","10.180.11.128:8888","10.180.11.130:8888");
public static String getServer(String client){
int nodeCount = 40;
TreeMap<Integer,String> treeMap = new TreeMap<>();
for(String s : list) {
for(int i = 0; i < nodeCount; i++) {
treeMap.put((s + "address:" + i).hashCode(), s);
}
}
SortedMap<Integer,String> sortedMap = treeMap.tailMap(client.hashCode());
Integer firstHash = (sortedMap.size() > 0) ? sortedMap.firstKey() : treeMap.firstKey();
return treeMap.get(firstHash);
}
public static void main(String[] args) {
for(int i = 0; i < 100; i++) {
System.out.println(getServer("用户:" + i + "访问"));
}
}
}