专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
芋道源码  ·  面试官:为什么数据库连接很消耗资源? ·  7 小时前  
ImportNew  ·  Redis 之父:哪怕被喷我也要说,AI ... ·  2 天前  
小鹿学Java  ·  Java 泛型 T,E,K,V,?,傻傻分不清? ·  2 天前  
小鹿学Java  ·  Java 泛型 T,E,K,V,?,傻傻分不清? ·  2 天前  
51好读  ›  专栏  ›  ImportNew

几种简单的负载均衡算法及其 Java 代码实现

ImportNew  · 公众号  · Java  · 2016-12-24 20:26

正文

请到「今天看啥」查看全文


serverWeightMap.put("192.168.1.109", 1);

serverWeightMap.put("192.168.1.110", 1);

}

}


轮询(Round Robin)法


轮询法即Round Robin法,其代码实现大致如下:


public class RoundRobin

{

private static Integer pos = 0;

public static String getServer()

{

// 重建一个Map,避免服务器的上下线导致的并发问题

Map serverMap =

new HashMap ();

serverMap.putAll(IpMap.serverWeightMap);

// 取得Ip地址List

Set keySet = serverMap.keySet();

ArrayList keyList = new ArrayList ();

keyList.addAll(keySet);

String server = null;

synchronized (pos)

{

if (pos > keySet.size())

pos = 0;

server = keyList.get(pos);

pos ++;

}

return server;

}

}


由于serverWeightMap中的地址列表是动态的,随时可能有机器上线、下线或者宕机,因此为了避免可能出现的并发问题,方法内部要新建局部变量serverMap,现将serverMap中的内容复制到线程本地,以避免被多个线程修改。这样可能会引入新的问题,复制以后serverWeightMap的修改无法反映给serverMap,也就是说这一轮选择服务器的过程中,新增服务器或者下线服务器,负载均衡算法将无法获知。新增无所谓,如果有服务器下线或者宕机,那么可能会访问到不存在的地址。因此,服务调用端需要有相应的容错处理,比如重新发起一次server选择并调用。


对于当前轮询的位置变量pos,为了保证服务器选择的顺序性,需要在操作时对其加锁,使得同一时刻只能有一个线程可以修改pos的值,否则当pos变量被并发修改,则无法保证服务器选择的顺序性,甚至有可能导致keyList数组越界。


轮询法的优点在于:试图做到请求转移的绝对均衡。


轮询法的缺点在于:为了做到请求转移的绝对均衡,必须付出相当大的代价,因为为了保证pos变量修改的互斥性,需要引入重量级的悲观锁synchronized,这将会导致该段轮询代码的并发吞吐量发生明显的下降。


随机(Random)法


通过系统随机函数,根据后端服务器列表的大小值来随机选择其中一台进行访问。由概率统计理论可以得知,随着调用量的增大,其实际效果越来越接近于平均分配流量到每一台后端服务器,也就是轮询的效果。


随机法的代码实现大致如下:


public class Random

{

public static String getServer()







请到「今天看啥」查看全文