文章目录


参考:

Java代码实现负载均衡五种算法

概况

Java代码实现负载均衡五种算法_权重

轮询法

轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。

  • 优点:绝对公平
  • 缺点:无法根据服务器性能去分配,无法合理利用服务器资源。
@Configuration
@Slf4j
public class RoundMethod {

// 指向该服务的server的指针
AtomicInteger index = new AtomicInteger(0);

public String roundMethod(Map<String,Integer> serverMap){
// 服务名
Set<String> set = serverMap.keySet();
List<String> list = new ArrayList<>();
list.addAll(set);
String serverName = "";
if(index.get() == list.size()){
index.set(0);
}
int pos = index.getAndIncrement();
serverName = list.get(pos);
return serverName;
}

public static void main(String[] args) {
RoundMethod roundMethod = new RoundMethod();
//模拟eureka注册中心的服务信息列表,key:IP,value:权重
Map<String,Integer> map = new ConcurrentHashMap<>();
map.put("192.168.13.1",1);
map.put("192.168.13.2",1);
map.put("192.168.13.3",1);
for(int i = 0;i < 10;i++){
String s = roundMethod.roundMethod(map);
log.info("------------>>>>>>" + s);
}
}
}

加权轮询法

该算法中,每个机器接受的连接数量是按权重比例分配的。这是对普通轮询算法的改进,比如你可以设定:第三台机器的处理能力是第一台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第3台机器。

@Slf4j
@Configuration
public class RoundWeightMethod {

// 指向该服务的server的指针
AtomicInteger index = new AtomicInteger(0);

public String roundWeightMethod(Map<String,Integer> serverMap){
// 服务名
Set<String> set = serverMap.keySet();
// 放所有的server。可重复,根据权重放
List<String> list = new ArrayList<>();
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
String serverName = iterator.next();
// 取出权重
int weight = serverMap.get(serverName);
// 放入权重个serverName到list中
for(int i = 0;i < weight;i++){
list.add(serverName);
}
}
String res = "";
if(index.get() == list.size()){
index.set(0);
}
int pos = index.getAndIncrement();
res = list.get(pos);
return res;
}

public static void main(String[] args) {
RoundWeightMethod roundMethod = new RoundWeightMethod();
//模拟eureka注册中心的服务信息列表,key:IP,value:权重
Map<String,Integer> map = new ConcurrentHashMap<>();
map.put("192.168.13.1",1);
map.put("192.168.13.2",1);
map.put("192.168.13.3",1);
for(int i = 0;i < 10;i++){
String s = roundMethod.roundWeightMethod(map);
log.info("------------>>>>>>" + s);
}
}
}

随机法

负载均衡方法随机的把负载分配到各个可用的服务器上,通过随机数生成算法选取一个服务器

@Slf4j
@Configuration
public class RandomMethod {

// 指向该服务的server的指针
AtomicInteger index = new AtomicInteger(0);

public String randomMethod(Map<String,Integer> serverMap){
// 服务名
Set<String> set = serverMap.keySet();
List<String> list = new ArrayList<>();
list.addAll(set);
String serverName = "";
Random random = new Random();
int pos = random.nextInt(list.size());
serverName = list.get(pos);
return serverName;
}

public static void main(String[] args) {
RandomMethod roundMethod = new RandomMethod();
//模拟eureka注册中心的服务信息列表,key:IP,value:权重
Map<String,Integer> map = new ConcurrentHashMap<>();
map.put("192.168.13.1",1);
map.put("192.168.13.2",1);
map.put("192.168.13.3",1);
for(int i = 0;i < 10;i++){
String s = roundMethod.randomMethod(map);
log.info("------------>>>>>>" + s);
}
}
}

加权随机法

在随机法的基础上加上权重,权重大的被使用的概率也会增大

@Slf4j
@Configuration
public class RandomWeightMethod {

// 指向该服务的server的指针
AtomicInteger index = new AtomicInteger(0);

public String randomWeightMethod(Map<String,Integer> serverMap){
// 服务名
Set<String> set = serverMap.keySet();
// 放所有的server。可重复,根据权重放
List<String> list = new ArrayList<>();
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
String serverName = iterator.next();
// 取出权重
int weight = serverMap.get(serverName);
// 放入权重个serverName到list中
for(int i = 0;i < weight;i++){
list.add(serverName);
}
}
String res = "";
Random random = new Random();
int pos = random.nextInt(list.size());
res = list.get(pos);
return res;
}

public static void main(String[] args) {
RandomWeightMethod roundMethod = new RandomWeightMethod();
//模拟eureka注册中心的服务信息列表,key:IP,value:权重
Map<String,Integer> map = new ConcurrentHashMap<>();
map.put("192.168.13.1",1);
map.put("192.168.13.2",2);
map.put("192.168.13.3",3);
for(int i = 0;i < 10;i++){
String s = roundMethod.randomWeightMethod(map);
log.info("------------>>>>>>" + s);
}
}
}

IP哈希法

根据客户端的IP进行哈希算法求出请求的机器

@Configuration
public class IpHashMethod {


// 1.定义map, key-ip,value-weight
static Map<String,Integer> ipMap=new HashMap<>();
static {
ipMap.put("192.168.13.1",1);
ipMap.put("192.168.13.2",2);
ipMap.put("192.168.13.3",4);
}
public String ipHash(String clientIP){
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);
// 2.取出来key,放到set中
Set<String> ipset=ipServerMap.keySet();
// 3.set放到list,要循环list取出
ArrayList<String> iplist=new ArrayList<String>();
iplist.addAll(ipset);
//对ip的hashcode值取余数,每次都一样的
int hashCode=clientIP.hashCode();
int serverListsize=iplist.size();
int pos=hashCode%serverListsize;
return iplist.get(pos);
}

public static void main(String[] args) {
IpHashMethod iphash=new IpHashMethod();
String servername= iphash.ipHash("192.168.21.2");
System.out.println(servername);
}
}