负载均衡算法

简介: 本文介绍五种负载均衡算法:随机、轮询、最小活跃数、源地址哈希与一致性哈希,涵盖适用场景及实现原理,并结合代码与图示解析其调度机制,适用于分布式系统流量分配设计参考。

随机

调用关系如上图(简化了公网->防火墙处理),适合场景:所有服务器性能基本一致,且无超阈值流量。

private K doSelect(List<K> nodes, String ip) {
    // 在列表中随机选取一个节点
    int index = random.nextInt(nodes.size());
    return nodes.get(index);
}

如果存在部分机器性能更优,此时可以在随机基础上增加权重,升级为:随机权重算法。

private K doSelect(List<K> nodes, String ip) {
    int length = nodes.size();
    AtomicInteger totalWeight = new AtomicInteger(0);
    for (K node : nodes) {
        Integer weight = node.getWeight();
        totalWeight.getAndAdd(weight);
    }
    if (totalWeight.get() > 0) {
        int offset = random.nextInt(totalWeight.get());
        for (N node : nodes) {
            // 让随机值 offset 减去当前node权重值
            offset -= node.getWeight();
            if (offset < 0) {
                // 当前node大于随机值offset,返回此Node
                return node;
            }
        }
    }
    // 随机返回
    return nodes.get(random.nextInt(length));
}

轮询

轮询不再是在多台服务器随机挑选,而是按照顺序一个个排队调用,调用完再插入队尾等待下一次调用

protected K doSelect(List<K> nodes, String ip) {
    int length = nodes.size();
    // 如果位置值已经等于长度重置为0(走一轮了)
    position.compareAndSet(length, 0);
    N node = nodes.get(position.get());
    // 数据原子增加,对应调用从1->2->3->4
    position.getAndIncrement();
    return node;
}

同加权随机,轮询也同样存在加权轮询的场景,此时流量调度将发生如下变化:

此处逻辑相对复杂,笔者在此说出主要思路,后续有时间补充伪代码,感兴趣的可以参照Dubbo的实现

如上有服务器servers=[A,B],对应权重weights=[3,1],总权重为4。我们可以理解为有4台服务器,3台A,1台B,一次调用过来的时候,需要按顺序访问。如有5次调用,调用顺序为AAABA。

选举思路如下:

次数

WeightedRoundRobin

选择结果

选择后的WeightedRoundRobin

1

3、1

A

2、1

2

2、1

A

1、1

3

1、1

A

0、1

4

0、1

B

0、0(等于0-0时复原成:3、1)

5

3、1

A

2、1

最小活跃数

指:将当前请求转发到连接数/请求数最少的机器上,其特点是根据服务器实时运行状态动态分配,保障服务负载不会过饱和。如下图当请求4过来时,Nginx判断目前服务器1连接数>服务器2,故4会请求到服务器2上:

源地址哈希

根据请求源IP哈希计算得到一个数值,用该数值在候选服务器列表的进行取模运算,得到的结果便是选中的服务器,此操作可以保证固定IP的请求总是到某一台服务器上,伪代码如下:

private K doSelect(List<K> nodes, String ip) {
    int length = nodes.size();
    int index = hash(ip) % length;
    return nodes.get(index);
}

一致性哈希

相同的请求尽可能落到同一个服务器上。一致性哈希解决稳定性问题,可以将所有的存储节点排列在首尾相接的 Hash 环上,每个 key 在计算 Hash 后会 顺时针找到临接的存储节点存放。而当有节点加入或退出时,仅影响该节点在 Hash环上顺时针相邻的后续节点。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
7天前
|
机器学习/深度学习 传感器 人工智能
对抗样本攻击详解:如何让AI模型产生错误判断
对抗样本是通过微小扰动欺骗机器学习模型的输入,人眼难辨却致模型高置信度误判。其原理源于模型线性特性,如FGSM利用梯度符号生成扰动。此类攻击具迁移性,可跨模型生效,但亦可用于对抗训练,提升模型鲁棒性与泛化能力。
38 0
|
7天前
|
存储 负载均衡 Java
Sentinel工作原理
Sentinel 是面向分布式服务架构的流量治理组件,以“资源”为核心概念,通过流量控制、熔断降级、系统负载保护等规则保障系统稳定。支持灵活配置与动态调整,实现高可用防护。
|
6天前
|
负载均衡 Java 应用服务中间件
Nacos注册中心
本文介绍了Nacos的安装部署、服务注册与发现、分级模型、负载均衡策略、权重控制、环境隔离及临时/持久化实例等核心功能,涵盖从本地启动到生产级配置的完整实践流程。通过实际操作演示了如何整合Spring Cloud Alibaba实现服务治理,并深入解析其架构设计与应用场景。
 Nacos注册中心
|
7天前
|
SQL 容灾 数据库
分布式事务Seata
本章学习分布式事务问题及解决方案,涵盖CAP、BASE理论,并深入讲解Seata框架的XA、AT、TCC、SAGA四种模式原理与实现,掌握跨服务事务一致性处理及高可用部署。
 分布式事务Seata
|
7天前
|
SQL 容灾 Nacos
Seata的部署和集成
本文介绍Seata TC服务器的部署与微服务集成,包括下载、解压、配置修改、数据库表创建及启动步骤,并实现基于Nacos的高可用与异地容灾集群,提升分布式事务可靠性。
|
7天前
|
自然语言处理 关系型数据库 MySQL
数据聚合、自动补全、数据同步
本文介绍了Elasticsearch中数据聚合、自动补全及数据同步的实现方法。通过聚合功能可对数据进行分组统计与指标计算,支持桶(Bucket)、度量(Metric)和管道(Pipeline)三种类型,并结合DSL与Java API 实现高效查询分析。为提升搜索体验,利用拼音分词器与Completion Suggester实现输入提示功能。同时,通过RabbitMQ异步消息机制实现MySQL与Elasticsearch间的数据同步,确保数据一致性,提高系统解耦性与实时性。(239字)
|
7天前
|
JSON 算法 Java
DSL语法、搜索结果处理
本文介绍了Elasticsearch(ES)的数据搜索功能,涵盖DSL查询语法、全文检索、精确查询、地理坐标查询及复合查询等类型。通过RestClient实现搜索,并结合黑马旅游案例,演示了酒店搜索、过滤、竞价排名等功能的实现过程,帮助读者掌握ES在实际项目中的应用。
 DSL语法、搜索结果处理
|
6天前
|
消息中间件 存储 Java
消息中间件RabbitMQ(高级)
本文深入探讨RabbitMQ在生产环境中的高级应用,涵盖消息可靠性、延迟消息、消息堆积及集群高可用等核心问题。通过生产者确认、持久化、消费者确认机制确保消息不丢失;利用TTL与死信交换机实现延迟队列;借助惰性队列提升堆积能力;最后通过普通集群、镜像集群及仲裁队列实现高可用架构。
 消息中间件RabbitMQ(高级)
|
7天前
|
监控 Java 测试技术
微服务保护Sentinel
本课程深入讲解微服务中雪崩问题的成因及解决方案,重点介绍阿里开源流量治理组件Sentinel的应用。涵盖Sentinel的部署与整合、限流模式(直接、关联、链路)、流控效果(快速失败、预热、排队等待)、熔断降级、线程隔离、授权规则及规则持久化等内容,结合Jmeter压测实战,帮助开发者全面提升微服务稳定性与高可用能力。
|
7天前
|
存储 NoSQL 网络协议
Redis集群部署指南
本教程基于CentOS7讲解Redis集群搭建,涵盖单机安装、主从复制、哨兵模式及分片集群的配置与测试,详细演示了多实例部署、节点关联、故障转移与数据分片等核心操作。
 Redis集群部署指南