您的位置:首页 > 编程语言 > Java开发

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

2017-10-26 20:30 537 查看
前言:
  
     负载均衡是为了解决并发情况下,多个请求访问,把请求通过提前约定好的规则转发给各个server。其中有好几个种经典的算法。在用java代码编写这几种算法之前,先来了解一下负载均衡这个概念。

1.概念
    负载,从字面意思可以分析,是指后端server可以承受的压力。这个一方面是服务器的性能,另一方面就是代码的质量了。
    均衡,就是说把服务部署在多态server,如何调度这些资源。根据服务器性能不同,进行一个权衡。
    当web访问量增加,服务器性能不同,更好的去利用服务器,我们需要负载均衡算法。

2.几种负载均衡算法简介



主要的负载均衡算法是图中这些,在代码实现之前,我们先简单回顾一下他们的概念。

轮询法:

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

   优点:绝对公平
   缺点:无法根据服务器性能去分配,无法合理利用服务器资源。

加权轮询法:

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

     什么是平滑的轮询,就是把每个不同的服务,平均分布。在Nginx源码中,实现了一种叫做平滑的加权轮询(smooth weighted round-robin balancing)的算法,它生成的序列更加均匀。5个请求现在分散开来,不再是连续的。

随机法:

    负载均衡方法随机的把负载分配到各个可用的服务器上,通过随机数生成算法选取一个服务器。毕竟随机,,有效性受到了质疑。

加权随机法:

     获取带有权重的随机数字,随机这种东西,不能看绝对,只能看相对。

IP_Hash算法:
 
    hash(object)%N算法,通过一种散列算法把请求分配到不同的服务器上。

3.Java代码实现负载均衡五种算法
    1.轮询法:
/**
* Title:轮询
* Description:
*
* @author Created by Julie
* @version 1.0
* @date on 15:49 2017/10/26
*/
package com.test.loadbalance;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class TestRoundRobin {

// 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",1);
ipMap.put("192.168.13.3",1);

}

// Integer sum=0;
Integer pos = 0;

public String RoundRobin(){
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);

String serverName=null;

// 4.定义一个循环的值,如果大于set就从0开始
synchronized(pos){
if (pos>=ipset.size()){
pos=0;
}
serverName=iplist.get(pos);
//轮询+1
pos ++;
}
return serverName;

}

public static void main(String[] args) {
TestRoundRobin testRoundRobin=new TestRoundRobin();
for (int i=0;i<10;i++){
String serverIp=testRoundRobin.RoundRobin();
System.out.println(serverIp);
}
}

}

    2.加权轮询法package com.test.loadbalance;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* Title:
* Description:加权轮询
*
* @author Created by Julie
* @version 1.0
* @date on 18:05 2017/10/26
*/
public class TestWeightRobin {
// 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);

}
Integer pos=0;
public String WeightRobin(){
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);

Set<String> ipSet=ipServerMap.keySet();
Iterator<String> ipIterator=ipSet.iterator();

//定义一个list放所有server
ArrayList<String> ipArrayList=new ArrayList<String>();

//循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量
while (ipIterator.hasNext()){
String serverName=ipIterator.next();
Integer weight=ipServerMap.get(serverName);
for (int i = 0;i < weight ;i++){
ipArrayList.add(serverName);
}
}
String serverName=null;
if (pos>=ipArrayList.size()){
pos=0;
}
serverName=ipArrayList.get(pos);
//轮询+1
pos ++;

return serverName;
}

public static void main(String[] args) {
TestWeightRobin testWeightRobin=new TestWeightRobin();
for (int i =0;i<10;i++){
String server=testWeightRobin.WeightRobin();
System.out.println(server);
}

}
}

     3.随机法:package com.test.loadbalance;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* Title:
* Description:随机
*
* @author Created by Julie
* @version 1.0
* @date on 18:25 2017/10/26
*/
public class TestRandom {
// 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 Random() {
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);

Set<String> ipSet=ipServerMap.keySet();

//定义一个list放所有server
ArrayList<String> ipArrayList=new ArrayList<String>();
ipArrayList.addAll(ipSet);

//循环随机数
Random random=new Random();
//随机数在list数量中取(1-list.size)
int pos=random.nextInt(ipArrayList.size());
String serverNameReturn= ipArrayList.get(pos);
return serverNameReturn;
}

public static void main(String[] args) {
TestRandom testRandom=new TestRandom();
for (int i =0;i<10;i++){
String server=testRandom.Random();
System.out.println(server);
}

}
}

    4.加权随机:package com.test.loadbalance;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
* Title:
* Description:加权随机
*
* @author Created by Julie
* @version 1.0
* @date on 18:42 2017/10/26
*/
public class TestRobinRandom {

// 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 RobinRandom(){
Map<String,Integer> ipServerMap=new ConcurrentHashMap<>();
ipServerMap.putAll(ipMap);

Set<String> ipSet=ipServerMap.keySet();
Iterator<String> ipIterator=ipSet.iterator();

//定义一个list放所有server
ArrayList<String> ipArrayList=new ArrayList<String>();

//循环set,根据set中的可以去得知map中的value,给list中添加对应数字的server数量
while (ipIterator.hasNext()){
String serverName=ipIterator.next();
Integer weight=ipServerMap.get(serverName);
for (int i=0;i<weight;i++){
ipArrayList.add(serverName);
}
}

//循环随机数
Random random=new Random();
//随机数在list数量中取(1-list.size)
int pos=random.nextInt(ipArrayList.size());
String serverNameReturn= ipArrayList.get(pos);
return serverNameReturn;
}

public static void main(String[] args) {
TestRobinRandom testRobinRandom=new TestRobinRandom();
for (int i =0;i<10;i++){
String server=testRobinRandom.RobinRandom();
System.out.println(server);
}

}
}

    5.IP_Hash算法:package com.test.loadbalance;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
* Title:
* Description:
*
* @author Created by Julie
* @version 1.0
* @date on 18:35 2017/10/26
*/
public class ipHash {
// 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) {
ipHash iphash=new ipHash();
String servername= iphash.ipHash("192.168.21.2");
System.out.println(servername);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: