负载均衡算法--源地址哈希法(Hash)
接上一篇博文:负载均衡算法–平滑加权轮询法(Smooth Weight Round Robin)。顾名思义,该算法是根据请求来源的地址求哈希值获取服务器的。算法描述假设有 N 台服务器 S = {S0, S1, S2, …, Sn-1},算法可以描述为:1、通过指定的哈希函数,计算请求来源的地址的哈希值2、对哈希值进行求余,底数为 N3、将余数作为索引值,从 S 中获取对应的服务器;假...
接上一篇博文:负载均衡算法–平滑加权轮询法(Smooth Weight Round Robin)。接下来介绍源地址哈希法。
源地址哈希法是根据请求来源的地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一源地址的请求,当服务器列表不变时,它每次都会映射到同一台服务器进行访问。
算法描述
假设有 N 台服务器 S = {S0, S1, S2, …, Sn-1},算法可以描述为:
1、通过指定的哈希函数,计算请求来源的地址的哈希值
2、对哈希值进行求余,底数为 N
3、将余数作为索引值,从 S 中获取对应的服务器;
假定我们现在有如下四台服务器:
服务器地址 | 权重 |
---|---|
192.168.1.1 | 1 |
192.168.1.2 | 2 |
192.168.1.3 | 3 |
192.168.1.4 | 4 |
源地址哈希法与权重没有关系,只与源地址有关。
代码实现
1、服务器管理类
package org.learn.loadbalance;
import java.util.Map;
import java.util.TreeMap;
/**
* @author zhibo
* @date 2019/5/16 16:25
*/
public class ServerManager {
public volatile static Map<String, Integer> serverMap = new TreeMap<>();
static {
serverMap.put("192.168.1.1", 1);
serverMap.put("192.168.1.2", 2);
serverMap.put("192.168.1.3", 3);
serverMap.put("192.168.1.4", 4);
}
}
2、源地址哈希类
package org.learn.loadbalance;
import java.util.ArrayList;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author zhibo
* @date 2019/5/16 16:28
*/
public class HashBalance {
public static String getServer(String sourceIp) {
if(sourceIp == null){
return "";
}
Set<String> serverSet = ServerManager.serverMap.keySet();
ArrayList<String> serverList = new ArrayList<>(serverSet);
Integer index = sourceIp.hashCode() % serverList.size();
return serverList.get(index);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
String server = getServer("ip" + new Random().nextInt(1000));
System.out.println(server);
}
}
}
执行 main 方法输出结果如下:
优点:
源地址哈希法可以保证,只要请求源地址不变,总会请求到相同的目标服务器。在早些时候进行 Web 开发时,是基于 Session 进行用户鉴权的,用户登录后,会在登录时的服务器A的 Session 中设置用户信息,如果下一次请求被分配到服务器B上,那么此时因 Session 中没有用户信息而报错。在这种场景下一般会使用源地址哈希法进行负载均衡,保证用户每次都可以访问到 Session 信息。当然现在的一般不会使用 Session 进行鉴权了,大都采用 redis、memcached 等缓存服务来解决 Session 不共享的问题。
缺点:
源地址哈希法可以保证,只要请求源地址不变,总会请求到相同的目标服务器。这样会带来两个问题:
1、由于用户的活跃度不同,可能会有大量的活跃用户被哈希到相同的服务器上,造成该服务器特别繁忙,大量的非活跃用户被哈希到相同的服务器上,造成该服务器几乎没有请求,造成请求不均衡。
2、一旦某个服务器挂掉,那么哈希到该服务器的所有源请求都会失败,直到服务恢复或者服务器列表中去掉该服务器。
文章内容仅代表个人观点,如有不正之处,欢迎批评指正,谢谢大家。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)