1.轮询法(Roud Robin)
按照请求顺序轮流分配到部署的服务器上。轮询的关键代码如下:
class RoudRobin{
private int pos=0;
private List<String> serverList;
/*
serverList.put("192.168.1.1")
serverList.put("192.168.1.2")
.......
serverList.put("192.168.1.8")
*/
piblic static String getServer(){
ArrayList <String> ipList=new ArrayList<String>();
ipList.addAll(serverList);
String ipServer=null;
Synchronized(pos){
if(pos>=ipList.size()){
pos=0;
}
server = ipList.get(pos);
pos++
}
return ipServer;
}
}
在我们的生产中,serverList中的地址是随时有可能变化的,因为服务器可能根据需求增加、减少,或者因为故障导致服务器宕机,为防止出现数组越界等并发情况出现,将服务器地址复制一份到ipList。但是当从局部变量中感知服务器地址的时,也会有缺陷,在本轮服务器选择中,无法感知到新增或者删除的服务器,当面对宕机或者下线的服务器,不能及时感知,为此需要重新发起一次路由。
轮询的目的在于绝对公平,完全不考虑每台服务的性能。
2.URL_HASH
按照访问地址的hash结果分配请求。源地址哈希算法的关键代码如下:
class URL_HASH{
private int pos=0;
private List<String> serverList;
/*
serverList.put("192.168.1.1")
serverList.put("192.168.1.2")
.......
serverList.put("192.168.1.8")
*/
public static getServer(String remoteIP){
List<String> ipList = new ArrayList <String>();
ipList.addAll(serverList);
int hashCode = remoteIP.hashCode();
int size = ipList.size();
int serverPos = hashCode % size;
return ipList.get(serverPos);
}
从代码中可以看出相同客户端的IP地址将会访问到同一服务器地址(hash码相同)直至服务器列表发生变化。相当于HTTP变得有状态。
3.加权轮询(Weight Roud Robin)
生产上的多台服务器间配置和负载不一定完全相同,每台服务器的处理数据的能力也不一样。负载时理想的状态是 配置高、负载低的服务器处理尽量多的请求,配置低、负载高的则相反。加权负载就是为了应对这种需求。
public class WeightRoudRobin{
private Map<String,Integer> serverWeightMap;//配置文件获取值
/* 值假设为
serverWeightMap.put("192.168.1.1",2);
serverWeightMap.put("192.168.1.2",1);
serverWeightMap.put("192.168.1.3",5);
.........
serverWeightMap.put("192.168.1.`0",3);
*/
public static String getServer(){
Map<String , Integer> serverMap = new HashMap<String,Integer>();
serverMap.putAll(serverWeightMap);
set<String> keySet=serverMap.keySet();
IteRator < String >it =keySet.iteRator();
List <String> serverList = new ArrayList <String> () ;
//生成加权的IP地址列表
while ( it.hasNext() ){
String server = it.netx();
Integer weight = serverMap.get(server);
for ( int i=0; i<weight; i++){
serverList.add ( server);
}
}
String server=null;
synchronized ( pos ){
if (pos>=serverList.size()){
pos=0;
}
server = serverList.get( pos );
pos ++ ;
}
return server;
}
}
4. 加权随机 (Weight Random)
和加权轮询法类似,加权随机法也是根据服务器的性能不同给予不同权重,不同之处在于是随机选取,而不是顺序。
public class WeightRandom{
private Map<String,Integer> serverWeightMap;//配置文件获取值
/* 值假设为
serverWeightMap.put("192.168.1.1",2);
serverWeightMap.put("192.168.1.2",1);
serverWeightMap.put("192.168.1.3",5);
.........
serverWeightMap.put("192.168.1.`0",3);
*/
public static String getServer(){
Map<String , Integer> serverMap = new HashMap<String,Integer>();
serverMap.putAll(serverWeightMap);
set<String> keySet=serverMap.keySet();
IteRator < String >it =keySet.iteRator();
List <String> serverList = new ArrayList <String> () ;
//生成加权的IP地址列表
while ( it.hasNext() ){
String server = it.netx();
Integer weight = serverMap.get(server);
for ( int i=0; i<weight; i++){
serverList.add ( server);
}
}
String server=null;
Ramdom random =new Random () ;
int randomPos = random.nextInt (serverList.size () );
String server = serverList.get(randomPos);
return server;
}
}