加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

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

发布时间:2019-04-13 06:20:40 所属栏目:外闻 来源:博客园
导读:副标题#e# 1.什么是负载均衡 负载均衡,英文 名称为Load Balance,指由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助。通过某种 负载分担技术,将外部发送来的请求均匀分配到对称

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

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

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

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

03.随机(Random)法

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

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

  1. public class Random 
  2.     public static String getServer() 
  3.     { 
  4.         // 重建一个Map,避免服务器的上下线导致的并发问题 
  5.         Map<String, Integer> serverMap =  
  6.                 new HashMap<String, Integer>(); 
  7.         serverMap.putAll(IpMap.serverWeightMap); 
  8.  
  9.         // 取得Ip地址List 
  10.         Set<String> keySet = serverMap.keySet(); 
  11.         ArrayList<String> keyList = new ArrayList<String>(); 
  12.         keyList.addAll(keySet); 
  13.  
  14.         java.util.Random random = new java.util.Random(); 
  15.         int randomPos = random.nextInt(keyList.size()); 
  16.  
  17.         return keyList.get(randomPos); 
  18.     } 

整体代码思路和轮询法一致,先重建serverMap,再获取到server列表。在选取server的时候,通过Random的nextInt方法取0~keyList.size()区间的一个随机值,从而从服务器列表中随机获取到一台服务器地址进行返回。基于概率统计的理论,吞吐量越大,随机算法的效果越接近于轮询算法的效果。

04.源地址哈希(Hash)法

源地址哈希的思想是获取客户端访问的IP地址值,通过哈希函数计算得到一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是要访问的服务器的序号。源地址哈希算法的代码实现大致如下:

  1. public class Hash 
  2.     public static String getServer() 
  3.     { 
  4.         // 重建一个Map,避免服务器的上下线导致的并发问题 
  5.         Map<String, Integer> serverMap =  
  6.                 new HashMap<String, Integer>(); 
  7.         serverMap.putAll(IpMap.serverWeightMap); 
  8.  
  9.         // 取得Ip地址List 
  10.         Set<String> keySet = serverMap.keySet(); 
  11.         ArrayList<String> keyList = new ArrayList<String>(); 
  12.         keyList.addAll(keySet); 
  13.  
  14.         // 在Web应用中可通过HttpServlet的getRemoteIp方法获取 
  15.         String remoteIp = "127.0.0.1"; 
  16.         int hashCode = remoteIp.hashCode(); 
  17.         int serverListSize = keyList.size(); 
  18.         int serverPos = hashCode % serverListSize; 
  19.  
  20.         return keyList.get(serverPos); 
  21.     } 

前两部分和轮询法、随机法一样就不说了,差别在于路由选择部分。通过客户端的ip也就是remoteIp,取得它的Hash值,对服务器列表的大小取模,结果便是选用的服务器在服务器列表中的索引值。

源地址哈希法的优点在于:保证了相同客户端IP地址将会被哈希到同一台后端服务器,直到后端服务器列表变更。根据此特性可以在服务消费者与服务提供者之间建立有状态的session会话。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读