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

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 上一篇文章我讲了关于负载均衡的三种算法,轮询法,随机法,最小连接法,这三种负载均衡的算法,但是关于负载均衡还有其他的算法,我们也需要你去看,而且在面试的过程中,很有可能是会问到的呦。对于要实现高性能集群,选择好负载均衡器很重要,同时针对不同的业务场景选择合适的负载均衡算法也是非常重要的。之前已经罗列出几个了,接下来在说剩下的几个算法,

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

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

1. 源地址哈希算法

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

源地址哈希法的思想是根据服务消费者请求客户端的 IP 地址,通过哈希函数计算得到一个哈希值,将此哈希值和服务器列表的大小进行取模运算,得到的结果便是要访问的服务器地址的序号。采用源地址哈希法进行负载均衡,相同的 IP 客户端,如果服务器列表不变,将映射到同一个后台服务器进行访问。

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

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);
   }

这段代码来自 Will.Shun 所写,我当时看到的时候也不是很明白什么意思,后来看了一下,其实和它的解释很类似,通过哈希函数计算得到一个哈希值,将此哈希值和服务器列表的大小进行取模运算,得到的结果便是要访问的服务器地址的序号。

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 权威指南》。


好了各位读者朋友们,以上就是本文的全部内容了。能看到这里的都是最优秀的程序员,我们必须要伸出骄傲的大拇指为你点个赞👍。如果觉得不过瘾,还想看到更多,再给大家推荐几篇。

HashMap 在多线程环境下操作可能会导致程序死循环

线程安全之synchronized关键字

当我们谈容器的时候,我们在谈什么

灵魂拷问:Java如何获取数组和字符串的长度?length还是length()?

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

one more thing!如果大家想要在最短的时间内成为一名 Java 大神,可以扫描下方的二维码,加入我们的知识星球。我们下篇文章见!

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
24天前
|
负载均衡 算法 Java
Spring Cloud全解析:负载均衡算法
本文介绍了负载均衡的两种方式:集中式负载均衡和进程内负载均衡,以及常见的负载均衡算法,包括轮询、随机、源地址哈希、加权轮询、加权随机和最小连接数等方法,帮助读者更好地理解和应用负载均衡技术。
|
2月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
2月前
|
算法 Go
[go 面试] 雪花算法与分布式ID生成
[go 面试] 雪花算法与分布式ID生成
|
6天前
|
机器学习/深度学习 JavaScript 算法
面试中的网红虚拟DOM,你知多少呢?深入解读diff算法
该文章深入探讨了虚拟DOM的概念及其diff算法,解释了虚拟DOM如何最小化实际DOM的更新,以此提升web应用的性能,并详细分析了diff算法的实现机制。
|
2月前
|
负载均衡 监控 算法
揭秘负载均衡的五大算法秘籍:让你的服务器轻松应对亿万流量,不再崩溃!
【8月更文挑战第31天】在互联网快速发展的今天,高可用性和可扩展性成为企业关注的重点。负载均衡作为关键技术,通过高效分配网络流量提升系统处理能力。本文介绍了轮询、加权轮询、最少连接及IP哈希等常见负载均衡算法及其应用场景,并提供Nginx配置示例。此外,还探讨了如何根据业务需求选择合适算法、配置服务器权重、实现高可用方案、监控性能及定期维护等最佳实践,助力系统优化与用户体验提升。
56 2
|
2月前
|
JavaScript 算法 索引
【Vue面试题二十三】、你了解vue的diff算法吗?说说看
这篇文章深入分析了Vue中的diff算法,解释了其在新旧虚拟DOM节点比较中的工作机制,包括同层节点比较、循环向中间收拢的策略,并通过实例演示了diff算法的执行过程,同时提供了源码层面的解析,说明了当数据变化时,如何通过Watcher触发patch函数来更新DOM。
【Vue面试题二十三】、你了解vue的diff算法吗?说说看
|
2月前
|
算法
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
聊聊一个面试中经常出现的算法题:组合运算及其实际应用例子
|
2月前
|
存储 负载均衡 算法
[go 面试] 一致性哈希:数据分片与负载均衡的黄金法则
[go 面试] 一致性哈希:数据分片与负载均衡的黄金法则
|
2月前
|
机器学习/深度学习 算法 数据中心
【机器学习】面试问答:PCA算法介绍?PCA算法过程?PCA为什么要中心化处理?PCA为什么要做正交变化?PCA与线性判别分析LDA降维的区别?
本文介绍了主成分分析(PCA)算法,包括PCA的基本概念、算法过程、中心化处理的必要性、正交变换的目的,以及PCA与线性判别分析(LDA)在降维上的区别。
51 4
|
2月前
|
算法
突击面试:解密面试官的算法题集合
突击面试:解密面试官的算法题集合
下一篇
无影云桌面