Nacos深度剖析与实践应用之-负载均衡

news2025/5/11 4:10:37

💡简介

        Nacos不仅提供服务注册与发现功能,还内置了强大的负载均衡能力。Nacos的负载均衡机制主要应用于服务消费者从服务注册中心获取服务实例列表后如何选择其中一个实例进行调用的过程。

🧠 学习目的 

这篇文章我们将探讨负载均衡🚨 ,我们希望达成以下具体的目标:

  1. ✅ 深入剖析负载均衡的特点。
  2. ✅ 理解负载均衡的实现流程。
  3. ✅ Nacos 整合负载均衡策略详解。

🉐 Nacos负载均衡的特点

  • ✔️ 客户端负载均衡:与传统的服务端负载均衡(如Nginx)不同,Nacos实现的是客户端负载均衡。

  • ✔️ 多种均衡策略:支持多种负载均衡算法,可扩展。

  • ✔️ 健康检查机制:自动过滤不健康实例。

  • ✔️ 权重支持:支持基于权重的流量分配。

🔢 Nacos负载均衡流程

        1️⃣ 服务消费者从Nacos Server获取服务实例列表。

        2️⃣ 客户端根据负载均衡策略选择一个实例。

        3️⃣ 向选定的实例发起请求。

        4️⃣ 记录调用结果。

🛒负载均衡策略 

 随机策略(RandomRule)

public Server choose(ILoadBalancer lb, Object key) {
    Server server = null;
    while (server == null) {
        // 1. 获取可用实例列表(健康状态)
        List<Server> upList = lb.getReachableServers(); 
        // 2. 获取全量实例列表(包括不健康实例)
        List<Server> allList = lb.getAllServers(); 
        
        int serverCount = allList.size();
        if (serverCount == 0) { // 无实例直接返回
            return null;
        }
        
        // 3. 生成随机索引(全量列表范围)
        int index = rand.nextInt(serverCount); 
        // 4. 从可用列表中获取实例(可能为null)
        server = upList.get(index); 
    }
    return server;
}

随机选择逻辑

allList的范围内生成随机索引(index = rand.nextInt(serverCount)),确保每个实例理论上有均等的被选概率。

  1. 潜在问题:若upListallList不一致(如部分实例不健康),直接通过upList.get(index)可能导致:
  2. 源码中通过while (server == null)重试,但可能陷入死循环(需依赖外部中断)。
  3. 随机索引超出upList范围 → 抛出IndexOutOfBoundsException

 设计缺陷与改进

问题:未显式处理upList与allList的差异,可能选到不健康实例。
修复方案:应在upList范围内生成随机索引(如下方优化代码)。

public Server choose(ILoadBalancer lb, Object key) {
    List<Server> upList = lb.getReachableServers();
    if (upList.isEmpty()) {
        return null; // 无健康实例直接返回
    }
    int index = rand.nextInt(upList.size()); // 仅在健康实例中随机
    return upList.get(index);
}

轮询策略(RoundRobinRule)

public Server choose(ILoadBalancer lb, Object key) {
    Server server = null;
    int count = 0; // 重试计数器(避免无限循环)
    while (server == null && count++ < 10) {
        // 1. 获取实例列表
        List<Server> reachableServers = lb.getReachableServers(); // 健康实例
        List<Server> allServers = lb.getAllServers();            // 全量实例
        int upCount = reachableServers.size();
        int serverCount = allServers.size();

        // 2. 空列表检查
        if ((upCount == 0) || (serverCount == 0)) {
            return null;
        }

        // 3. 计算下一个实例索引(原子递增取模)
        int nextServerIndex = incrementAndGetModulo(serverCount);
        server = allServers.get(nextServerIndex);

        // 4. 有效性检查
        if (server == null) {
            Thread.yield(); // 让出CPU避免忙等待
            continue;
        }

        // 5. 健康检查(需实例实现isAlive等方法)
        if (server.isAlive() && server.isReadyToServe()) {
            return server;
        }
        server = null; // 实例不健康则重试
    }
    return server; // 超过重试次数返回null或最后尝试的实例
}
  • incrementAndGetModulo():通过原子操作(AtomicInteger)递增索引并取模,确保线程安全。
  • isAlive()isReadyToServe():需服务实例实现这些方法(如Nacos实例默认健康状态由ServerListFilter维护)。
  • 重试与退出机制最多重试10次,避免因实例频繁变动导致无限循环。
  • Thread.yield():在竞争激烈时让出CPU。

 权重策略(NacosWeightedRule)



java
public Instance chooseInstance(List<Instance> instances) {
    // 根据权重值进行选择
    if (CollectionUtils.isEmpty(instances)) {
        return null;
    }
    
    double[] weights = new double[instances.size()];
    double totalWeight = 0;
    
    for (int i = 0; i < instances.size(); i++) {
        weights[i] = instances.get(i).getWeight();
        totalWeight += weights[i];
    }
    
    double randomWeight = random.nextDouble() * totalWeight;
    double tempWeight = 0;
    
    for (int i = 0; i < weights.length; i++) {
        tempWeight += weights[i];
        if (randomWeight <= tempWeight) {
            return instances.get(i);
        }
    }
    
    return instances.get(0);
}

Nacos的权重算法基于加权随机(Weighted Random)实现,通过为每个服务实例分配权重值,控制流量分配比例。其核心逻辑如下:

  • 权重计算:每个实例的权重值(weight)与其被选中的概率成正比。例如,实例A权重为2,实例B权重为1,则A被选中的概率是B的2倍 。
  • 随机选择:生成一个[0, totalWeight)范围内的随机数,遍历实例列表累加权重,直到随机数落在某实例的权重区间内,即选中该实例 。
  • 健康检查:仅从健康实例(isHealthy=true)中选择,避免故障实例参与分配 。

三种策略类型对比

策略类型特点使用场景优缺点
随机策略(RandomRule)- 完全随机选择实例
- 实现简单
- 无状态
- 实例性能均匀的环境
- 快速验证场景
- 无特殊路由要求的服务调用
✅ 优点:实现简单,无状态
❌ 缺点:无法考虑实例负载差异,可能不均匀
轮询策略(RoundRobinRule)- 按顺序依次选择
- 均匀分配请求
- 无权重考虑
- 实例配置相同的集群
- 需要严格均匀分配的场景
- 无状态服务
✅ 优点:请求分配绝对均匀
❌ 缺点:无法应对性能差异的实例
权重策略(NacosWeightedRule)- 根据控制台配置的权重分配
- 支持动态调整
- 考虑实例性能差异
- 实例配置不均的环境
- 灰度发布
- 金丝雀发布
- 根据硬件性能分配流量
✅ 优点:最灵活,支持动态调整
❌ 缺点:需要合理设置权重值

🚀小结

Nacos的负载均衡通过客户端动态决策和服务端健康管理的结合,实现了高可用与灵活性。其核心价值在于:

  • 智能化流量分配:权重与健康检查机制保障服务稳定性 。
  • 运维便捷性:控制台实时调整参数。

对于微服务架构,合理选择负载均衡策略并持续监控调优,是提升系统弹性和性能的关键。

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

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

相关文章

Photoshop安装与配置--简单攻略版

下载地址:Photoshop软件工具下载 安装完成后&#xff0c;即可运行Photoshop.exe&#xff1b;打开工具页面后&#xff0c;按照下面简单配置即可 1.编辑-》首选项-》常规 或者直接快捷键CtrlK 暂存盘&#xff1a;一定要设置为非C盘 2.性能 3.文件处理 以上配置比较基础&#xf…

桌面级OTA测试解决方案:赋能智能网联汽车高效升级

一、前言 随着智能网联汽车的快速发展&#xff0c;OTA&#xff08;Over-The-Air&#xff09;技术已成为汽车软件更新和功能迭代的关键手段。为确保OTA升级的可靠性、安全性和效率&#xff0c;构建一套高效、便捷的桌面级OTA测试解决方案至关重要。 本方案基于Vector先进的软硬…

PG,TRPO,PPO,GRPO,DPO原理梳理

强化学习方法的分类 一、基础概念 Policy Model&#xff08;Actor Model&#xff09;&#xff1a;根据输入文本&#xff0c;预测下一个token的概率分布&#xff0c;输出下一个token也即Policy模型的“动作”。该模型需要训练&#xff0c;是我们最终得到的模型&#xff0c;并由上…

Cursor新版0.49.x发布

小子看到 Cursor 0.49.x 版本正式发布&#xff0c;截止今天已经有两个小patch版本&#xff01;本次更新聚焦于 自动化Rules生成、改进的 Agent Terminal 以及 MCP 图像支持&#xff0c;并带来了一系列旨在提升编码效率和协作能力的改进与修复。 以下是本次更新的详细内容&…

每日算法-250419

每日算法 - 2024年4月19日 记录今天完成的LeetCode算法题。 1710. 卡车上的最大单元数 题目描述 思路 贪心 解题过程 目标是最大化卡车可以装载的单元总数。根据贪心策略&#xff0c;我们应该优先装载单位体积&#xff08;每个箱子&#xff09;包含单元数 (numberOfUnitsPerB…

PDF转excel+json ,vue3+SpringBoot在线演示+附带源码

在线演示地址&#xff1a;Vite Vuehttp://www.xpclm.online/pdf-h5 源码gitee前后端地址&#xff1a; javapdfexcel: javaPDF转excelhttps://gitee.com/gaiya001/javapdfexcel.git 盖亚/vuepdfhttps://gitee.com/gaiya001/vuepdf.git 后续会推出 前端版本跟nestjs版本 识别复…

如何高效使用 Text to SQL 提升数据分析效率?四个关键应用场景解析

数据分析师和业务人员常常面临这样的困境&#xff1a;有大量数据等待分析&#xff0c;但 SQL 编写却成为效率瓶颈。即使对于经验丰富的数据分析师来说&#xff0c;编写复杂 SQL 查询也需要耗费大量时间&#xff1b;而对于不具备 SQL 专业知识的业务人员&#xff0c;数据分析则更…

分享一个DeepSeek+自建知识库实现人工智能,智能回答高级用法。

这个是我自己搞的DeepSeek大模型自建知识库相结合到一起实现了更强大的回答问题能力还有智能资源推荐等功能。如果感兴趣的小伙伴可以联系进行聊聊&#xff0c;这个成品已经有了实现了&#xff0c;所以可以融入到你的项目&#xff0c;或者毕设什么的还可以去参加比赛等等。 1.项…

jangow靶机笔记(Vulnhub)

环境准备&#xff1a; 靶机下载地址&#xff1a; https://download.vulnhub.com/jangow/jangow-01-1.0.1.ova kali地址&#xff1a;192.168.144.128 靶机&#xff08;jangow&#xff09;地址&#xff1a;192.168.144.180 一.信息收集 1.主机探测 使用arp-scan进行主机探…

PyTorch `flatten()` 和 `squeeze()` 区别

PyTorch flatten() 和 squeeze() 区别 在 PyTorch 里,flatten() 和 squeeze(0) 是两个不同的张量操作, 1. flatten() 方法 flatten() 方法用于把一个多维张量展开成一维张量。它会将张量里的所有元素按顺序排列成一个一维序列。 语法 torch.flatten(input, start_dim=

wordpress SMTP配置qq邮箱发送邮件,新版QQ邮箱授权码获取方法

新版的QQ邮箱界面不同了&#xff0c;以下是新版的设置方法&#xff1a; 1. 进入邮箱后&#xff0c;点右上角的设置图标&#xff1a; 2. 左下角的菜单里&#xff0c;选择“账号与安全” &#xff1a; 3. 然后如下图&#xff0c;开启SMTP 服务&#xff1a; 4. 按提示验证短信&am…

2025年最新版 Git和Github的绑定方法,以及通过Git提交文件至Github的具体流程(详细版)

文章目录 Git和Github的绑定方法与如何上传至代码仓库一. 注册 GitHub 账号二.如何创建自己的代码仓库&#xff1a;1.登入Github账号&#xff0c;完成登入后会进入如下界面&#xff1a;2.点击下图中红色框选的按钮中的下拉列表3.选择New repostitory4.进入创建界面后&#xff0…

基于LSTM-AutoEncoder的心电信号时间序列数据异常检测(PyTorch版)

心电信号&#xff08;ECG&#xff09;的异常检测对心血管疾病早期预警至关重要&#xff0c;但传统方法面临时序依赖建模不足与噪声敏感等问题。本文使用一种基于LSTM-AutoEncoder的深度时序异常检测框架&#xff0c;通过编码器-解码器结构捕捉心电信号的长期时空依赖特征&#…

JavaScript中的Event事件对象详解

一、事件对象&#xff08;Event&#xff09;概述 1. 事件对象的定义 event 对象是浏览器自动生成的对象&#xff0c;当用户与页面进行交互时&#xff08;如点击、键盘输入、鼠标移动等&#xff09;&#xff0c;事件触发时就会自动传递给事件处理函数。event 对象包含了与事件…

王牌学院,25西电通信工程学院(考研录取情况)

1、通信工程学院各个方向 2、通信工程学院近三年复试分数线对比 学长、学姐分析 由表可看出&#xff1a; 1、信息与通信工程25年相较于24年上升5分、军队指挥学25年相较于24年上升30分 2、新一代电子信息技术&#xff08;专硕&#xff09;25年相较于24年下降25分、通信工程&…

深入理解 Java 多线程:锁策略与线程安全

文章目录 一、常见的锁策略1. 乐观锁&&悲观锁2. 读写锁3. 重量级锁&&轻量级锁4. 自旋锁5. 公平锁&&不公平锁6. 可重入锁 && 不可重入锁 二、CAS1. 什么是 CAS2. CAS 是怎么实现的3.CAS 有哪些应用1) 实现原子类2) 实现自旋锁 4. CAS 的 ABA 问…

Java数据结构——ArrayList

Java中ArrayList 一 ArrayList的简介二 ArrayList的构造方法三 ArrayList常用方法1.add()方法2.remove()方法3.get()和set()方法4.index()方法5.subList截取方法 四 ArrayList的遍历for循环遍历增强for循环(for each)迭代器遍历 ArrayList问题及其思考 前言 ArrayList是一种 顺…

科学量化AI对品牌产品印象 首个AI印象(AII)指数发布

2025年4月18日&#xff0c;营销传播数据研究领先机构四度传播研究院(SAC)&#xff0c;正式推出了量化AI大模型对产品整体印象的AI印象&#xff0c;简称AII&#xff08;ARTIFICIAL INTELLIGENCE IMPRESSIONS&#xff09;&#xff0c;同时发布了首个“汽车AI印象榜”。为企业和消…

FFmpeg 硬核指南:从底层架构到播放器全链路开发实战 基础

目录 1.ffmpeg的基本组成2.播放器的API2.1 复用器阶段2.1.1 分配解复用上下文2.1.2 文件信息操作2.1.3 综合示例 2. 2 编解码部分2.2.1 分配解码器上下文2.2.2编解码操作2.2.3 综合示例 3 ffmpeg 内存模型3.1 基本概念3.2API 1.ffmpeg的基本组成 模块名称功能描述主要用途AVFo…

UE5有些场景的导航生成失败解决方法

如果导航丢失&#xff0c;就在项目设置下将&#xff1a; 即可解决问题&#xff1a; 看了半个小时的导航生成代码发现&#xff0c;NavDataSet这个数组为空&#xff0c;导致异步构建导航失败。 解决 NavDataSet 空 无法生成如下&#xff1a; 当 NavDataSet 为空的化 如果 bAut…