负载均衡算法

简介: 本文介绍了五种负载均衡算法:随机、轮询、最小活跃数、源地址哈希与一致性哈希。涵盖适用场景、核心思想及实现逻辑,重点解析加权随机与轮询的进阶应用,并结合代码与图示说明各算法调度机制,适用于分布式系统流量分发策略设计。

随机

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

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应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
4月前
|
存储 缓存 Java
自动装配机制
本文深入解析SpringBoot自动装配机制,围绕@SpringBootApplication注解展开,剖析其组合注解(@ComponentScan、@SpringBootConfiguration、@EnableAutoConfiguration)的源码实现,重点讲解自动配置的加载流程与核心原理。
 自动装配机制
|
数据可视化 Swift 开发者
零一万物开源Yi系列“理科状元”Yi-9B,消费级显卡可跑,魔搭社区最佳实践
零一万物发布并开源了Yi系列中的“理科状元”——Yi-9B,可在魔搭体验
|
4月前
|
监控 新能源 人机交互
探索热辐射:红外发射率的调控艺术与应用(隐身篇)
红外辐射无处不在,物体通过热辐射在空气中传播红外线,而8~14μm等“大气窗口”波段可被探测。红外热成像仪利用温度差异生成图像,广泛应用于军事侦察。实现红外隐身需降低辐射强度,主要途径包括调控发射率、控制温度及阻隔传播。低发射率涂层、隔热材料、相变材料(如VO₂)、超材料与仿生设计等技术不断发展,推动智能、多频谱兼容隐身材料研发。EM10便携式测量仪实现3-5μm与8-14μm双波段同步高精度检测,助力材料研发与现场质量监控,促进红外隐身技术向高效、协同、实用化方向迈进。
|
7月前
|
运维 Kubernetes Cloud Native
K8s
Kubernetes,源自Google的开源容器编排平台,被誉为数字时代的“隐形操作系统”。它以声明式API和控制器模式为核心,实现应用的自动化部署、扩缩容与自愈,支撑全球企业云原生转型。从微服务到AI、边缘计算,K8s正构建统一的分布式应用基石,重塑软件交付与运维范式,成为数字化世界的底层引擎。(238字)
【VMware】WIN11/WIN11家庭版禁用Device Guard
【VMware】WIN11/WIN11家庭版禁用Device Guard
|
负载均衡 算法 定位技术
负载均衡
负载均衡
546 57
|
12月前
|
Shell
亲测好用!解决国内短信受限的办法分享
随着国内多个平台暂停对个人用户的短信发送服务,不少人面临困扰。为此推荐一款实用工具——Spug推送平台,可满足发送短信验证码等需求。通过简单的注册、创建模板与调用接口步骤,即可快速实现短信发送功能。例如,使用bash命令调用接口:`curl https://push.spug.cc/send/xxx?code=6677&targets=151xxxx0875`。注意遵守平台规则和法律法规,确保正常使用。在短信权限受限的情况下,Spug无疑是个人用户的理想选择。
608 3
亲测好用!解决国内短信受限的办法分享
|
运维 监控 算法
基于 Python 迪杰斯特拉算法的局域网计算机监控技术探究
信息技术高速演进的当下,局域网计算机监控对于保障企业网络安全、优化资源配置以及提升整体运行效能具有关键意义。通过实时监测网络状态、追踪计算机活动,企业得以及时察觉潜在风险并采取相应举措。在这一复杂的监控体系背后,数据结构与算法发挥着不可或缺的作用。本文将聚焦于迪杰斯特拉(Dijkstra)算法,深入探究其在局域网计算机监控中的应用,并借助 Python 代码示例予以详细阐释。
276 6
|
Java
【Java】俄罗斯方块小游戏(附源码)
【Java】俄罗斯方块小游戏(附源码)
831 1
|
前端开发 开发者
如何理解 package.json 中的 proxy 字段?
`package.json` 中的 `proxy` 字段用于配置代理服务器,帮助前端开发中解决跨域问题及模拟后端响应。其基本概念、使用场景及配置方法将在本文中详细探讨,助力开发者高效调试与测试。
489 4

热门文章

最新文章