源地址哈希法的优点在于:保证了相同客户端IP地址将会被哈希到同一台后端服务器,直到后端服务器列表变更。根据此特性可以在服务消费者与服务提供者之间建立有状态的session会话。
  源地址哈希算法的缺点在于:除非集群中服务器的非常稳定,基本不会上下线,否则一旦有服务器上线、下线,那么通过源地址哈希算法路由到的服务器是服务器上线、下线前路由到的服务器的概率非常低,如果是session则取不到session,如果是缓存则可能引发”雪崩”。如果这么解释不适合明白,可以看我之前的一篇文章MemCache超详细解读,一致性Hash算法部分。
  加权轮询(Weight Round Robin)法
  不同的服务器可能机器配置和当前系统的负载并不相同,因此它们的抗压能力也不尽相同,给配置高、负载低的机器配置更高的权重,让其处理更多的请求,而低配置、高负载的机器,则给其分配较低的权重,降低其系统负载。加权轮询法可以很好地处理这一问题,并将请求顺序按照权重分配到后端。加权轮询法的代码实现大致如下:
  public class WeightRoundRobin
  {
  private static Integer pos;
  public static String getServer()
  {
  // 重建一个Map,避免服务器的上下线导致的并发问题
  Map<String, Integer> serverMap =
  new HashMap<String, Integer>();
  serverMap.putAll(IpMap.serverWeightMap);
  // 取得Ip地址List
  Set<String> keySet = serverMap.keySet();
  Iterator<String> iterator = keySet.iterator();
  List<String> serverList = new ArrayList<String>();
  while (iterator.hasNext())
  {
  String server = iterator.next();
  int weight = serverMap.get(server);
  for (int i = 0; i < weight; i++)
  serverList.add(server);
  }
  String server = null;
  synchronized (pos)
  {
  if (pos > keySet.size())
  pos = 0;
  server = serverList.get(pos);
  pos ++;
  }
  return server;
  }
  }
  与轮询法类似,只是在获取服务器地址之前增加了一段权重计算的代码,根据权重的大小,将地址重复地增加到服务器地址列表中,权重越大,该服务器每轮所获得的请求数量越多。
  加权随机(Weight Random)法
  与加权轮询法类似,加权随机法也是根据后端服务器不同的配置和负载情况来配置不同的权重。不同的是,它是按照权重来随机选择服务器的,而不是顺序。加权随机法的代码实现如下:
  public class WeightRandom
  {
  public static String getServer()
  {
  // 重建一个Map,避免服务器的上下线导致的并发问题
  Map<String, Integer> serverMap =
  new HashMap<String, Integer>();
  serverMap.putAll(IpMap.serverWeightMap);
  // 取得Ip地址List
  Set<String> keySet = serverMap.keySet();
  Iterator<String> iterator = keySet.iterator();
  List<String> serverList = new ArrayList<String>();
  while (iterator.hasNext())
  {
  String server = iterator.next();
  int weight = serverMap.get(server);
  for (int i = 0; i < weight; i++)
  serverList.add(server);
  }
  java.util.Random random = new java.util.Random();
  int randomPos = random.nextInt(serverList.size());
  return serverList.get(randomPos);
  }
  }
  这段代码相当于是随机法和加权轮询法的结合,比较好理解,不解释了。
  小连接数(Least Connections)法
  前面几种方法费尽心思来实现服务消费者请求次数分配的均衡,当然这么做是没错的,可以为后端的多台服务器平均分配工作量,大程度地提高服务器的利用率,但是实际情况是否真的如此?实际情况中,请求次数的均衡真的能代表负载的均衡吗?这是一个值得思考的问题。
  上面的问题,再换一个角度来说是:以后端服务器的视角来观察系统的负载,而非请求发起方来观察。小连接数法便属于此类。
  小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它正是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数少的一台服务器来处理当前请求,尽可能地提高后端服务器的利用效率,将负载合理地分流到每一台机器。由于小连接数设计服务器连接数的汇总和感知,设计与实现较为繁琐,此处不说它的实现了。