每个Java程序员都必须知道的四种负载均衡算法

news2024/11/25 6:54:27

前言

一般来说,我们在设计系统的时候,为了系统的高扩展性,会尽可能的创建无状态的系统,这样我们就可以采用集群的方式部署,最终很方便的根据需要动态增减服务器数量。但是,要使系统具有更好的可扩展性,除了无状态设计之外,还要考虑采用什么负载均衡算法,本文就带领大家认识以下常见的4种负载均衡算法。

什么是负载均衡

负载均衡是指多台服务器以对称的方式组成一个服务器集群。每台服务器的地位相当(但不同的服务器可能性能不同),可以独立提供服务,无需其他服务器的辅助。为了保证系统的可扩展性,需要有一种算法能够将系统负载平均分配给集群中的每台服务器。这种算法称为负载均衡算法。负责执行负载均衡算法并平均分配请求的服务器称为负载均衡器。

随机算法

随机算法非常简单,该算法的核心是通过随机函数随机获取一个服务器进行访问。假设我们现在有四台服务器,192.168.1.1~ 192.168.1.4, 该算法用java实现大致如下:

public class RandomTest {

    private static final List<String> servers = Arrays.asList("192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4");

    public static String getServer() {
        Random random = new Random();
        int index = random.nextInt(servers.size());
        return servers.get(index);
    }


    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            String server = getServer();
            System.out.println("select server: "+server);
        }
    }
}
复制代码

当样本较小时,算法可能分布不均匀,但根据概率论,样本越大,负载会越均匀,而负载均衡算法本来就是为应对高并发场景而设计的。该算法的另一个缺点是所有机器都有相同的访问概率, 如果服务器性能不同,负载将不平衡。

轮询算法

Round-Robin轮询算法是另一种经典的负载均衡算法。请求以循环的方式分发到集群中的所有服务器。同理,对于上述四台服务器,假设客户端向集群发送10个请求,则请求分布将如下图所示:

在十个请求中,第一、第五和第九个请求将分配给192.168.1.1,第二、第六和第十个请求将分配给192.168.1.2,依此类推。我们可以看到round-robin算法可以在集群中均匀的分配请求。但是,该算法具有与随机算法相同的缺点,如果服务器性能不同,负载将不平衡,因此需要加权轮询算法。

加权轮询算法

Weighted Round-Robin加权轮询算法是在round-robin算法的基础上根据服务器的性能分配权重。服务器能支持的请求越多,权重就越高,分配的请求也就越多。对于同样的10个请求,使用加权轮询算法的请求分布会如下图所示:

可以看到192.168.1.4权重最大,分配的请求数最多。看一下使用Java简单实现的以下加权循环算法。

public class RoundRobinTest {

    public class Node{
        private String ip;

        private Integer weight;

        private Integer currentWeight;

        public Node(String ip,Integer weight) {
            this.ip = ip;
            this.weight = weight;
            this.currentWeight = weight;
        }

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public Integer getWeight() {
            return weight;
        }

        public void setWeight(Integer weight) {
            this.weight = weight;
        }

        public Integer getCurrentWeight() {
            return currentWeight;
        }

        public void setCurrentWeight(Integer currentWeight) {
            this.currentWeight = currentWeight;
        }
    }

    List<Node> servers = Arrays.asList(
            new Node("192.168.1.1",1),
            new Node("192.168.1.2",2),
            new Node("192.168.1.3",3),
            new Node("192.168.1.4",4));
    private Integer totalWeight;

    public RoundRobinTest() {
        this.totalWeight = servers.stream()
                .mapToInt(Node::getWeight)
                .reduce((a,b)->a+b).getAsInt();
    }


    public String getServer() {
        Node node = servers.stream().max(Comparator.comparingInt(Node::getCurrentWeight)).get();
        node.setCurrentWeight(node.getCurrentWeight()-totalWeight);
        servers.forEach(server->server.setCurrentWeight(server.getCurrentWeight()+server.getWeight()));
        return node.getIp();
    }


    public static void main(String[] args) {
        RoundRobinTest roundRobinTest = new RoundRobinTest();
        for (int i = 0; i < 10; i++) {
            String server = roundRobinTest.getServer();
            System.out.println("select server: "+server);
        }
    }
复制代码

该算法的核心是的动态计算currentWeight。每个服务器被选中后,currentWeight需要减去所有服务器的权重之和,这样可以避免权重高的服务器一直被选中。权重高的服务器有更多的分配请求,请求可以平均分配给所有服务器。

哈希算法

哈希算法,顾名思义,就是利用哈希表根据 计算出请求的路由hashcode%N。这里hashcode代表哈希值,N代表服务器数量。该算法的优点是实现起来非常简单。具体实现如下:

rivate static final List<String> servers = Arrays.asList("192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4");

    public static String getServer(String key) {
        int hash = key.hashCode();
        int index =  hash%servers.size();
        return servers.get(index);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            String server = getServer(String.valueOf(i));
            System.out.println("select server: "+server);
        }
    }
复制代码

哈希算法在很多缓存分布式存储系统中很常见,比如MemorycachedRedis,但是一般不会用到上面的哈希算法,而是优化后的一致性哈希算法。

总结

本文总结了负载均衡常见的4种算法,我们可以发现nginx或者spring cloud中的ribbon都使用到了这样的算法思想,我们可以根据自己的业务场景选择合适算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/154280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【UE4 第一人称射击游戏】32-添加击杀AI的提示功能(使用到控件蓝图的动画功能)

上一篇&#xff1a;【UE4 第一人称射击游戏】31-更好的UI界面本篇效果&#xff1a;可以看到在击杀AI后&#xff0c;右上角有击杀提示信息步骤&#xff1a;新建一个控件蓝图命名为“KillPopup”双击打开“KillPopup”&#xff0c;拖入一个图像控件&#xff0c;锚点设置为右上角&…

RobotFramework测试库

在RF 测试库里面&#xff0c;分为三种测试库标准测试库扩展测试库远程测试库标准测试库随 Robot Framework 版本一同发布的测试库&#xff0c; 不需要单独安装&#xff0c;但部分标准库仍然需要手动导入标准库有扩展测试库标准库以外的其他测试库都统称为扩展测试库&#xff0c…

OceanBase产品家族及基础概念

第二章&#xff1a;OceanBase产品家族及基础概念 1. OceanBase产品家族 1.1 OceanBase数据库产品家族 1.2 OceanBase数据库内核 1.2.1 高扩展 • 水平扩展 • 按需在线扩容、缩容、不停服务 • 单集群突破100台服务器 1.2.2 高性能 • 峰值6,100万次/秒&#xff08;真实业…

P12 PyTorch 常见函数梯度

目录&#xff1a;1&#xff1a; 常见函数的导数2: 梯度与微分的关系3: 常见函数的梯度4&#xff1a; 梯度更新常见问题一 常见函数的导数&#xff08;复合函数求导证明&#xff09;二 梯度与微分的关系2.1 微分&#xff1a; x 为一元变量时微分&#xff1a; x 为向量时微分矩阵…

学术加油站|机器学习应用在数据库调优领域的前沿工作解读

编者按 本文系北京理工大学科研助理牛颂登所著&#xff0c;本篇也是「 OceanBase 学术加油站」系列稿件第八篇。 「牛颂登&#xff1a;北京理工大学科研助理。 硕士期间在电子科技大学网络空间安全研究院从事聚类和强化学习相关算法研究&#xff0c;在应用聚类研究个性化在线学…

Python之Hermite多项式

文章目录Hermite多项式求导和积分求根和反演拟合其他Hermite多项式 Hermite多项式是一种非常重要的正交多项式&#xff0c;尤其在量子力学中&#xff0c;是谐振子的本征态&#xff0c;在物理学中&#xff0c;其定义为 Hn(x)(−1)nex2dndxne−x2H_n(x)(-1)^ne^{x^2}\frac{\text…

算法之动态规划实战

目录 前言&#xff1a; 如何量化两个字符串的相似度&#xff1f; 如何编程计算莱文斯坦距离&#xff1f; 如何编程计算最长公共子串长度&#xff1f; 参考资料 前言&#xff1a; 利用 Trie 树&#xff0c;可以实现搜索引擎的关键词提示功能&#xff0c;这样可以节省用户输…

【Python+pandas】学生测试成绩求和排序

✨博文作者 wangzirui32 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ &#x1f449;本文首发于CSDN&#xff0c;未经许可禁止转载 &#x1f60e;Hello&#xff0c;大家好&#xff0c;我是wangzirui32&#xff0c;最近时间不够充足&#xff0c;鸽了几个月&#xff0c;这是2023…

【蓝桥杯第十三届C++B组】真题训练(5 / 8) - java写法

目录 4402.刷题统计 - 数学模拟 4403. 修剪灌木 - 思维 4404. X 进制减法 - 进制运算 贪心 4405. 统计子矩阵 - 前缀和 双指针​​​​​​​ 1、一维前缀和 2、二维前缀和 4406. 积木画 - dp 1、找规律dp 4402.刷题统计 - 数学模拟 4402. 刷题统计 - AcWing题库 思…

素数(prime)总结

素数的介绍 素数定义 质数(prime number)又称素数&#xff0c;有无限个。一个大于1的自然数&#xff0c;除了1和它本身外&#xff0c;不能被其他自然数整除&#xff0c;换句话说就是该数除了1和它本身以外不再有其他的因数;否则称为合数。 根据算术基本定理&#xff0c;每一个…

linux 文件夹多用户共享 解决文件删除的Permission denied

linux文件属性基础 Linux文件属主和属组 通过命令ls 可以查看文件属性&#xff1a; zcargo-MS-7D53:~/Desktop/parent_ceshi$ ll -lh total 16K drwxrwxr-x 2 zc zc 4.0K 1月 10 13:59 ceshi/ drwxrwxr-x 2 zc zc 4.0K 1月 10 13:59 ceshi02/以上展示命令的意思&#xff1…

大数据概念及Hadoop介绍

大数据概念及Hadoop介绍大数据概念数据存储单位大数据定义大数据的特点(5V特征)大数据部门组织架构分布式技术负载均衡故障转移伸缩性分布式技术总结分布式和集群的区别Hadoop介绍Hadoop核心组件Hadoop发展简史Hadoop特性优点与行业应用Hadoop特性优点行业应用Hadoop发行版本及…

14、Java网络编程

一、 网络编程概述Java是 Internet 上的语言&#xff0c;它从语言级上提供了对网络应用程序的支持&#xff0c;程序员能够很容易开发常见的网络应用程序。Java提供的网络类库&#xff0c;可以实现无痛的网络连接&#xff0c;联网的底层细节被隐藏在 Java 的本机安装系统里&…

【广度优先搜索遍历 + 染色法】判断二分图

还记得当时才大一&#xff0c;上离散数学课&#xff0c;当时觉得很不屑&#xff0c;就是觉得这学的什么玩弄啥用没有&#xff0c;但是其实很多的算法思想在解决题目时很有价值。 本文就将使用染色法解决判断二分图问题&#xff0c;使用广度优先搜索遍历和 Java 语言实现 一、题…

车辆逆行识别检测系统 opencv

车辆逆行识别检测系统通过opencvyolo网络深度学习技术&#xff0c;对现场画面中车辆逆向行驶行为进行检测抓拍预警。 OpenCV的全称是Open Source Computer Vision Library&#xff0c;是一个跨平台的计算机视觉处理开源软件库&#xff0c;支持与计算机视觉和机器学习相关的众多…

嵌入式 LINUX 驱动开发 day02 字符设备驱动 字符设备驱动 虚拟串口, 一个驱动支持多个设备

1. 驱动开发 字符设备驱动 代码&#xff1a; vser.c #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h>#include <linux/fs.h> /***** 设备相关信息 ******/ static unsigned int VSER_MAJOR 256; //主设备号…

青铜到王者,9本最好的Python从入门到进阶的书

春节长假还有2周了&#xff0c;是时候囤一些书充充电了&#xff01;新的一年群里很多小伙伴开始想学Python&#xff0c; 无论是准备转行的&#xff0c;还是想多学一份技能提高职场竞争力的&#xff0c;都想选择Python赛道&#xff0c;下面给大家推荐一些非常不错的Python入门到…

【Flask框架】—— 30 Flask-RESTful

前后端分离和前后端不分离 前后端不分离 在前后端不分离的应用模式中&#xff0c;前端页面看到的效果都是由后端控制&#xff0c;由后端渲染页面或重定向&#xff0c;也就是后端需要控制前端的展示&#xff0c;前端与后端的耦合度很高。 这种应用模式比较适合纯网页应用&…

iclr 2022 Compositional attention: Disentangling search and retrieval

Mittal S, Raparthy S C, Rish I, et al. Compositional attention: Disentangling search and retrieval[J]. arXiv preprint arXiv:2110.09419, 2021. 目录Mittal S, Raparthy S C, Rish I, et al. Compositional attention: Disentangling search and retrieval[J]. arXiv p…

【Kettle报错】kettle7.0链接MySQL显示:No appropriate protocol

【Kettle7.0链接本地MySQL数据库报错】 1. 问题描述 报错问题&#xff1a;kettle7.0报错&#xff0c;提示No appropriate protocol (protocol is disabled or cipher suites are inappropriate) 错误原因&#xff1a; Caused by: javax.net.ssl.SSLHandshakeException: No a…