面试官:负载均衡的算法你了解不?

Posted Java极客技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试官:负载均衡的算法你了解不?相关的知识,希望对你有一定的参考价值。


上一篇文章我讲了关于负载均衡的三种算法,轮询法,随机法,最小连接法,这三种负载均衡的算法,但是关于负载均衡还有其他的算法,我们也需要你去看,而且在面试的过程中,很有可能是会问到的呦。

对于要实现高性能集群,选择好负载均衡器很重要,同时针对不同的业务场景选择合适的负载均衡算法也是非常重要的。之前已经罗列出几个了,接下来在说剩下的几个算法,

1. 源地址哈希算法

唯一不丢失策略的算法,但是负载均衡和源数据信息和哈希算法有很大关系。

还是之前的操作,伪代码:

private static Map<String, Integer> serviceWeightMap = new HashMap<String, Integer>();

static {
serviceWeightMap.put("192.168.1.100", 1);
serviceWeightMap.put("192.168.1.101", 1);
serviceWeightMap.put("192.168.1.102", 4);
serviceWeightMap.put("192.168.1.103", 1);
}

public static String testConsumerHash(String remoteIp) {

Map<String, Integer> serverMap = new HashMap<String, Integer>();
serverMap.putAll(serviceWeightMap);

//取得IP地址list
Set<String> keySet = serverMap.keySet();
ArrayList<String> keyList = new ArrayList<String>();
keyList.addAll(keySet);

int hashCode = remoteIp.hashCode();
int pos = hashCode % keyList.size();

return keyList.get(pos);
}

2. 加权轮询算法

再来看一下加权轮训算法,我们先看一下在 nginx 里面进行的权重配置:

http {
upstream cluster {
server a weight=1;
server b weight=2;
server c weight=3;
}

假如 Nginx 每收到 6 个客户端的请求,会把其中的 1 个转发给后端 a,把其中的 2 个转发给后端 b,把其中的 3 个转发给后端 c。

加权轮询算法的结果,就是要生成一个服务器序列。每当有请求到来时,就依次从该序列中取出下一个服务器用于处理该请求。

加权轮训算法伪代码:

private static Map<String, Integer> serviceWeightMap = new HashMap<String, Integer>();

static {
serviceWeightMap.put("192.168.1.100", 1);
serviceWeightMap.put("192.168.1.101", 1);
serviceWeightMap.put("192.168.1.102", 4);
serviceWeightMap.put("192.168.1.103", 1);
}


public static String testWeightRoundRobin() {

// 重新创建一个map,避免出现由于服务器上线和下线导致的并发问题
Map<String, Integer> serverMap = new HashMap<String, Integer>();
serverMap.putAll(serviceWeightMap);

//取得IP地址list
Set<String> keySet = serverMap.keySet();
Iterator<String> it = keySet.iterator();

List<String> serverList = new ArrayList<String>();

while (it.hasNext()) {
String server = it.next();
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;
}

其实在 加权轮训算法中,是有缺陷的,在某些特殊的权重下,加权轮询调度会生成不均匀的实例序列,这种不平滑的负载可能会使某些实例出现瞬时高负载的现象,导致系统存在宕机的风险。而为了解决这个调度的缺陷,后边就有平滑加权轮训调度,有兴趣的同学一定要去看一下这个平滑加权轮训。

3. 加权随机算法

加权随机法跟加权轮询法类似,根据后台服务器不同的配置和负载情况,配置不同的权重。不同的是,它是按照权重来随机选取服务器的,而非顺序。

    private static Map<String, Integer> serviceWeightMap = new HashMap<String, Integer>();

static {
serviceWeightMap.put("192.168.1.100", 1);
serviceWeightMap.put("192.168.1.101", 1);
serviceWeightMap.put("192.168.1.102", 4);
serviceWeightMap.put("192.168.1.103", 1);
}

public static String testWeightRandom() {
// 重新创建一个map,避免出现由于服务器上线和下线导致的并发问题
Map<String, Integer> serverMap = new HashMap<String, Integer>();
serverMap.putAll(serviceWeightMap);

//取得IP地址list
Set<String> keySet = serverMap.keySet();
List<String> serverList = new ArrayList<String>();
Iterator<String> it = keySet.iterator();

while (it.hasNext()) {
String server = it.next();
Integer weight = serverMap.get(server);
for (int i=0; i<weight; i++) {
serverList.add(server);
}
}

Random random = new Random();
int randomPos = random.nextInt(serverList.size());

String server = serverList.get(randomPos);

return server;
}

这里不同的地方就是服务器是通过随机算法获取。

其实我们可以想一个实例:比如说在以下场景:有一个集合 S,里面比如有 A,B,C,D 这四项。这时我们想随机从中抽取一项,但是抽取的概率不同,比如我们希望抽到 A 的概率是 50%,抽到 B 和 C 的概率是 20%,D 的概率是 10%。一般来说,我们可以给各项附一个权重,抽取的概率正比于这个权重。

4.HTTP 国际化

HTTP 报文中可以承载以任何语言表示的内容,就像它能承载图像、影片,或任何类型的 媒体那样。对 HTTP 来说,实体主体只是二进制信息的容器而已。

为了支持国际性的内容,服务器需要告知客户端每个文档的字母表和语言,这样客户端才 能正确地把文档中的信息解包为字符并把内容呈现给用户。

服务器通过 HTTP 协议的 Content-Type 首部中的 charset 参数和 Content-Language 首部告知客户端文档的字母表和语言。这些首部描述了实体主体的“信息盒子”里面装的是 什么,如何把内容转换成合适的字符以便显示在屏幕上以及里面的词语表示的是哪种语言。

同时,客户端需要告知服务器用户理解何种语言,浏览器上安装了何种字母表编码算法。客户端发送 Accept-Charset 首部和 Accept-Language 首部,告知服务器它理解哪些字 符集编码算法和语言以及其中的优先顺序。

关于 HTTP 我就给大家说这么多了,如果又兴趣的话,大家可以去看 《 HTTP 图解》,《HTTP 权威指南》。






日常操作来了!如果觉得这篇文章有点用的话,求在看、求转发,明人不说暗话,我们喜欢这种被大家伙宠爱的感觉。


以上是关于面试官:负载均衡的算法你了解不?的主要内容,如果未能解决你的问题,请参考以下文章

负载均衡的那些算法们

面试官问:HTTP 的负载均衡你了解么?你不是说了你们用的Nginx么?说一下把。

面试官:说说你知道的几种负载均衡分类

手把手教你写出 6 种负载均衡算法!

这可能是最简单的图解一致性哈希算法了!

浏览器负载均衡 进程内部层…那些你需要掌握的多级缓存