负载均衡算法

简介: 本文介绍多种负载均衡算法:随机、轮询、最小活跃数、源地址哈希及一致性哈希,适用于不同场景。随机适合性能一致的服务器;轮询按序调用;最小活跃数动态分配请求;源地址哈希保证IP固定路由;一致性哈希减少节点变动影响。

随机

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

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应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
1月前
|
人工智能 自然语言处理 数据挖掘
OpenClaw Skills是什么?2026年阿里云一键部署OpenClaw+Skills实战指南
在AI智能体全面渗透工作生活的2026年,OpenClaw(原Clawdbot/Moltbot)凭借开源灵活的特性,成为个人与中小企业打造专属AI助手的首选工具。而作为其核心扩展的OpenClaw Skills,更是将实用性推向新高度——这一场景化技能插件库已扩充至50+内置技能,覆盖办公效率、开发辅助、生活服务、运营推广等八大核心场景,通过模块化封装实现“零代码调用、全场景适配”。
643 2
|
3月前
|
负载均衡 应用服务中间件 Nacos
Nacos配置中心
本文详细介绍Nacos作为配置中心的实现原理与实战应用,涵盖配置管理、热更新、共享配置及优先级规则,并演示集群搭建与高可用部署,提升微服务架构下配置的动态管理能力。
|
3月前
|
存储 SQL Java
Spring Boot使用slf4j进行日志记录
本文介绍了在Spring Boot项目中使用SLF4J结合Logback进行日志管理的最佳实践。相比直接使用System.out.println(),SLF4J作为日志门面,解耦日志实现,提升可维护性。通过application.yml配置日志级别与logback.xml定义输出格式、路径、滚动策略等,实现灵活高效的日志记录。推荐遵循阿里巴巴开发规范,统一使用SLF4J API,便于日志系统替换与统一管理。
|
2月前
|
人工智能 算法 BI
企业 GEO 效果评估指标体系
本文构建了企业GEO优化效果评估指标体系,涵盖AI引用率、首条占位率、线索转化率等核心指标,结合收录率、关键词覆盖量等辅助指标,建立分层级监测模型,并配套工具与周期建议,助力企业科学评估并优化AI搜索表现。
|
3月前
|
数据采集 运维 供应链
RFID实现工业“智”造升级
在工业 4.0 与智能制造浪潮下,传统工业生产面临 “信息断层”“效率瓶颈”“质量追溯难” 等核心痛点。RFID技术凭借非接触式识别、多标签同时读取、抗恶劣环境、数据可读写等特性,成为打通生产全流程数据链路、实现 “人 - 机 - 料 - 法 - 环” 智能互联的关键技术,从底层数据采集到顶层决策优化,全面推动工业 “智” 造发展,RFID实现工业“智”造升级。
|
敏捷开发 数据可视化 搜索推荐
游戏开发团队必备!哪些办公软件能像板栗看板提升节日协作效率?
本文深入剖析了6款可视化团队协作办公软件在游戏行业的节日协作中的应用,包括板栗看板、Trello、Asana、飞书、Jira和Monday.com。这些工具通过任务可视化、团队协同、项目规划、即时通讯、工作流自动化等功能,助力游戏公司在节日期间高效协作,确保项目按时上线,提升游戏品质,最终为玩家带来精彩绝伦的游戏体验。
246 3
|
Windows
显示器设置
显示器设置
426 2
|
数据采集 安全 网络安全
提高企业进入国外市场的“免疫力”——阿里云CDN安全能力分析
提高企业进入国外市场的“免疫力”——阿里云CDN安全能力分析
|
Java 开发者
JAVA多线程初学者必看:为何选择继承Thread还是Runnable,这其中有何玄机?
【6月更文挑战第19天】在Java中创建线程,可选择继承Thread类或实现Runnable接口。继承Thread直接运行,但限制了多重继承;实现Runnable更灵活,允许多线程共享资源且利于代码组织。推荐实现Runnable接口,以保持类的继承灵活性和更好的资源管理。
312 2
|
算法 程序员 编译器
【cmake 踩坑记录】CMake文件安装深入解析:EXCLUDE的奥秘与替代方案
【cmake 踩坑记录】CMake文件安装深入解析:EXCLUDE的奥秘与替代方案
685 0

热门文章

最新文章