5. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Nacos

一、什么是Nacos

Nacos 是阿里巴巴开源的一款云原生应用基础设施,它旨在简化微服务架构中服务治理和配置管理的复杂性。通过 Nacos,服务在启动时可以自动注册,而其他服务则可以通过名称来查找并访问这些注册好的实例。同时,Nacos 内置了实时健康检查机制,能够监控各个服务实例的状态,确保只有健康的服务节点能够处理请求,从而提升整个系统的可靠性和稳定性。此外,Nacos 还提供了一个集中化的配置管理平台,使得应用能够在运行时动态更新配置而无需重启,这不仅大大降低了运维成本,也避免了因硬编码或分布式文件更新而带来的各种问题。得益于其与 Kubernetes、Spring Cloud、Dubbo 等流行框架的无缝集成,Nacos 为构建云原生和微服务架构提供了一整套简单而全面的解决方案。

二、启动Nacos

下面,我们来启动Naocs。启动Nacos前我们在官网下载Nacos压缩包,截至文章发布时Nacos的最新版是2.5.0,我们就使用这个版本来简单的讲解Nacos。
使用前需确保开发环境符合Nacos最低运行要求:

环境配置
JDK/JRE8及以上
CPU1核及以上,支持64位CPU
内存2G及以上
硬盘无最小要求,根据保留日志自行调整
操作系统Linux, Mac OS X, Windows

Tip:Nacos 2.50下载地址: https://download.nacos.io/nacos-server/nacos-server-2.5.0.zip?spm=5238cd80.2ef5001f.0.0.3f613b7cP0VdIa&file=nacos-server-2.5.0.zip

2.1 Windows 启动Nacos

在 Windows 环境下进入解压后的目录中找到 bin 文件夹。在该目录下,通过双击或在命令行中执行 startup.cmd 脚本(建议使用命令行执行脚本),如果使用命令行执行脚本需附加参数“-m standalone”来启动 Nacos 的单机模式,这时 Nacos 会在默认的 8848 端口启动服务,启动成功后你可以通过浏览器访问 http://localhost:8848/nacos 进行管理和配置。需要注意的是,启动前必须确保系统中已正确配置 JDK 环境变量,以便 Nacos 能够正常运行。

2.2 Linux 启动Nacos

在 Linux 系统上启动 Nacos 的流程与 Windows 类似,进入解压后的目录找到 bin 目录。为了在 Linux 环境下运行脚本,首先确认 startup.sh 文件具有可执行权限,如果没有可通过命令 chmod +x startup.sh 进行赋权。接下来,在终端中执行sh startup.sh -m standalone命令,即可启动 Nacos 的单机模式。启动完成后,Nacos 同样会监听默认的 8848 端口,我们可以通过浏览器访问管理界面。

Tip:如果通过双击startup.cmd 启动Nacos,会出现报错问题,这是因为startup.cmd 中默认设置的是集群模式运行,需要将文件中的MODE="cluster" 改为MODE="standalone",再次双击运行既可。

2.3 开启鉴权

一般情况下我们在开发时,不需要开启鉴权,但是有必要在这里说一下如何开启鉴权。进入Nacos目录下的conf目录,修改application.properties文件。
首先,我们需要配置自定义的用于生成JWT令牌的密钥,自定义密钥时,推荐将配置项设置为Base64编码的字符串,且原始密钥长度不得低于32字符:

nacos.core.auth.default.token.secret.key=生成JWT令牌的密钥

接着,配置用于服务端之间请求的身份识别信息:

nacos.core.auth.server.identity.key=服务器身份验证的键
nacos.core.auth.server.identity.value=服务器身份验证的值

最后,我i们就可以开启鉴权了:

# 使用哪种认证机制来进行身份验证和授权
nacos.core.auth.system.type=nacos
# 启用身份认证
nacos.core.auth.enabled=true

Tip:Nacos 的认证类型分为:内置认证nacos、OAuth2认证oauth2以及自定义认证custom

三、使用Nacos

3.1 服务注册与发现
  1. 什么是服务注册与发现
    服务发现和注册是微服务架构中的关键机制,用于动态管理和协调服务实例之间的通信。服务注册涉及将服务实例的信息(如名称、地址、端口)注册到一个服务注册中心。服务实例在启动时会向注册中心注册,并定期发送心跳信号以保持注册状态。
    服务发现则是指客户端或其他服务通过服务注册中心查找和访问服务实例的过程。服务发现有两种主要模式:客户端发现和服务端发现。在客户端发现模式中,客户端直接与注册中心通信获取服务实例信息;在服务端发现模式中,负载均衡器或API网关负责从注册中心获取服务信息并转发请求。
    这两者的结合实现了服务的动态扩展和高可用性,简化了微服务之间的通信配置,是构建大规模分布式系统的重要机制。

  2. 项目中使用服务发现与注册
    实现服务注册与发现,我们需要在项目中安装nacos-sdk-csharp.aspnetcore
    首先,我们新建项目 NacosDemo,在项目中增加两个Web Api 服务GoodsApiOrderApi,在这个项目中引入nacos-sdk-csharp.aspnetcore

    Tip:注意:不要安装带unoffical的nuget包,带unoffical包支支持Nacos 1.x。

    接着,在Program 类中新增服务注册的代码。

    // 将服务注册到nacos
    builder.Services.AddNacosAspNet(builder.Configuration);
    

    然后,我们需要在application.json文件中配置Nacos 服务发现。

    "Nacos": {
      "ServerAddresses": [
        "http://192.168.116.1:8848"
      ],
      "Namespace": "learning",
      "ServiceName": "GoodsApi",
      "GroupName": "DEFAULT_GROUP",
      "ClusterName": "DEFAULT",
      "Weight": 100,
      "Metadata": {
        "version": "1.0.0"
      },
      "username": "nacos",
      "password": "nacos",
      "RegisterEnabled": true,
      "InstanceEnabled": true,
      "Ephemeral": true
    }
    

    这个Nacos配置文件包含了服务注册和发现的详细信息。ServerAddresses是Nacos服务器的地址列表,Namespace表示服务所在的命名空间,这里命名为learningServiceName是注册服务的名称,GroupName是服务所属的分组,默认是DEFAULT_GROUPClusterName是服务所属的集群名称,默认是DEFAULTWeight表示服务实例的权重,用于负载均衡,这里设置为100。Metadata包含服务实例的元数据,版本信息为1.0.0usernamepassword是访问Nacos服务器的认证信息。RegisterEnabled表示是否启用服务注册,InstanceEnabled表示服务实例是否可用,Ephemeral表示服务实例是否为临时实例(非持久)。
    在配置中我们将服务设置为了临时实例,这里所说的临时实例是指在服务注册和发现系统中,注册中心不会持久化存储的服务实例。这种实例的信息不会被持久化存储在注册中心的数据库中,当服务实例失效或停止时,注册中心会自动删除该实例的信息,不会保留历史记录。临时实例适用于生命周期较短的服务实例,例如短期运行的批处理任务或临时性服务。如果临时实例在规定时间内未发送心跳信号,注册中心会自动将其移除,确保注册中心只保留当前活跃的服务实例,避免无效实例占用资源。临时实例适用于需要快速启动和停止的服务场景,例如容器化应用的实例管理,支持快速扩展和收缩服务实例数量。
    在上述Nacos配置中我们设置服务的权重为100,这个权重是用于服务实例负载均衡的重要参数。它决定了请求在多个服务实例之间的分配比例。具体来说,权重值越高的实例,被选择处理请求的概率就越大。通过设置不同的权重值,可以实现对服务实例的流量控制,优化系统性能和资源利用。里如,在微服务架构下,如果某个服务实例的硬件配置较高,处理能力较强,可以将其权重设置得更高,以便更多的请求能够分配到该实例,从而提高整体系统的效率。相反,如果某个实例的资源较为有限,则可以降低其权重,减少其负载压力。
    我们还需要在Nacos中新增命名空间,也就是配置中的Namespace。我们访问Nacos的管理界面,切换到命名空间界面,新增命名空间。
    在这里插入图片描述
    接下来我们在GoodsApiOrderApi两个Web Api服务中增加控制器GoodsController OrderController ,在这两个接口新增用来获取商品GetGoods和获取订单GetOrder的Action。其中GetGoods返回服务的Ip、端口号以及商品名,GetOrder通过服务发现,调用GoodsApiGetGoods接口并返回数据。这个流程模拟了订单获取商品信息的流程,很简单但能展示了Nacos服务发现的能力。

    using Microsoft.AspNetCore.Mvc;
    
    namespace GoodsApi.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class GoodsController : ControllerBase
        {
            [HttpGet]
            [Route("GetGoods")]
            public string GetGoods()
            {
                // 获取服务ip和端口
                var ip = HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString();
                var port = HttpContext.Connection.LocalPort;
                return "Goods Service,服务地址:" + ip + ":" + port+",商品列表:苹果、香蕉、橘子";
            }
        }
    }
    
    using Microsoft.AspNetCore.Mvc;
    using Nacos.V2;
    
    namespace OrderApi.Controllers;
    
    [ApiController]
    [Route("[controller]")]
    public class OrderController : ControllerBase
    {
        private readonly INacosNamingService _nacosNamingService;
    
        public OrderController(INacosNamingService nacosNamingService)
        {
            _nacosNamingService = nacosNamingService;
        }
        [HttpGet]
        [Route("GetOrder")]
        public  string GetOrder()
        {
            var instance = _nacosNamingService.SelectOneHealthyInstance("GoodsApi").Result;
            if (instance!=null)
            {
                // 调用GetGoods方法
                HttpClient client = new HttpClient();
                var response = client.GetAsync($"http://{instance.Ip}:{instance.Port}/api/Goods/GetGoods").Result;
                return $"Order Service,调用GoodsApi服务成功,调用GetGoods方法返回数据:{response.Content.ReadAsStringAsync().Result}";
            }
            else
            {
                return "Order Service,调用GoodsApi服务失败";
            }
        }
    }
    

    紧接着,我们启动项目调试代码。进入GohodsApi紧接着,我们启动项目调试代码。进入GoodsApi 接口项目的bin目录,开启两个命令窗口分别执行运行命令,指定不同的端口。同样在OrderApi接口项目的bin目录中执行运行命令。

    dotnet .\GoodsApi.dll --urls=http://localhost:5001/
    dotnet .\GoodsApi.dll --urls=http://localhost:5002/
    dotnet .\OrderApi.dll --urls=http://localhost:5003/
    

    执行上述命令后我们查看Nacos管理界面的服务列表,会看到两个GoodsApi服务和一个OrderApi服务。
    在这里插入图片描述
    最后,我们访问在浏览器中访问http://localhost:5003/order/GetOrder,会看到浏览器显示出了GetOrder中返回的内容,其中包含了GoodsApiGetGoods返回的内容。我们多刷新几次,会发现页面显示的GoodsApi的地址在改变,这说明Nacos 服务发现起了作用。
    在这里插入图片描述
    在这里插入图片描述

3.2 配置中心
  1. 什么是配置中心
    在以往的开发中,我们往往需要将数据库连接字符串这类的配置信息放在application.json文件中,这对于单体应用或服务数量不是很多的微服务应用来说没什么大问题,如果配置需要更新了,我们就直接去服务器上修改就可以,但是对于大型微服务应用来说将配置信息放在application.json中就显得很鸡肋了,每次修改配置信息去服务器上一个服务一个服务改的话是很麻烦的,而且还容易出错。这时我们就需要引入配置中心,配置中心是一种集中管理和分发应用配置的系统。它能够将配置从应用程序代码中分离出来,方便管理和修改。配置中心通常支持动态更新配置,不需要重启服务即可生效,并保障配置的一致性和可靠性。Nacos 就具备配置中心的功能。
  2. 项目中使用配置中心
    首先,我们需要在项目中引入Nacos 配置中心的nuget包nacos-sdk-csharp.extensions.configuration,这个包可以帮我们去监听配置的变化。
    其次,为了演示配置中心的使用,我们在Nacos管理界面的配置页面新增一个数据库配置GoodsDb
    在这里插入图片描述
    在这里插入图片描述
    接着,我们在GoodsApi项目的application.json文件的Nacos节点下增加需要监听的配置。
    "Listeners": [
      {
        "Optional":false,
        "DataId":"GoodsDb",
        "Group":"GoodsGroup"
      }
    ]
    
    这个配置表示一个监听器列表,包含一个监听器对象,Listeners表示配置监听器的数组,Optional表示监听器是否可选,false表示必需,DataId表示监听的配置项ID,这里是GoodsDbGroup表示配置项所属的组,这里是GoodsGroup,这个监听器用于监控GoodsGroup组中GoodsDb配置项的变化。
    然后,我们在GoodsApi项目中新增一个控制器DbTestController,并在其中编写GetDbConnectionString Action,这个Action中支是回去了数据库连接字符串,并将这个字符串返回给调用方。
    using Microsoft.AspNetCore.Mvc;
    
    namespace GoodsApi.Controllers;
    
    [ApiController]
    [Route("[controller]")]
    public class DbTestController : ControllerBase
    {
        /// <summary>
        /// 配置
        /// </summary>
        private IConfiguration _configuration;
        public DbTestController(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetDbConnectionString")]
        public string GetDbConnectionString()
        {
            // 从配置中获取数据库连接字符串
            return _configuration.GetConnectionString("GoodsDb");
        }
    } 
    
    最后,我们在浏览器中输入http://localhost:5001/dbtest/GetDbConnectionString即可看到我们在Nacos中配置的数据库链接字符串。这是我们修改Nacos中配置的链接字符串,再次刷新页面显示的连接字符串改变了。
    在这里插入图片描述
    在这里插入图片描述

    TIP:像数据库连接字符串这种在项目启动时就注入进来的配置,如果Nacos对应的配置修改后虽然会自动更新到项目中,但是我们的项目使用的链接字符串还是在启动时注入进来的旧的连接字符串,因此我们需要自己实现更新注入的连接字符串的代码。由于专栏不是专门讲Naocs的,因此在这里就不再讲解如何实现了。

四、总结

本文详细介绍了 Nacos 的概念、安装启动和使用方法,全面展示了 Nacos 在微服务架构中的重要作用。文章首先指出,Nacos 是阿里巴巴开源的云原生应用基础设施,通过自动注册和服务发现机制,使各服务实例能够动态注册、查询并健康检查,从而提升系统的稳定性和可靠性;同时,其集中化的配置管理平台能够让应用在运行时动态更新配置,彻底解决了硬编码或手动修改分布式文件所带来的维护困难和运维成本高的问题,并能与 Kubernetes、Spring Cloud、Dubbo 等流行框架无缝集成。接着,文章介绍了如何获取最新版 Nacos(以 2.5.0 为例),并列举了启动前的系统环境要求,包括 JDK 8 及以上、1 核 CPU、2G 内存等;详细说明了在 Windows 和 Linux 环境下分别如何通过命令行或脚本启动 Nacos 的单机模式,以及如何在启动脚本中调整模式设置。文章还讲解了如何开启鉴权,通过修改配置文件设定 JWT 密钥和服务间身份验证参数,保障访问安全。随后,文中通过一个基于 C# 的示例展示了如何在项目中使用 Nacos 实现服务注册与发现,说明了服务如何通过注册中心实现自动注册、权重路由和负载均衡,从而支持客户端动态调用其他服务;同时,也介绍了如何利用 Nacos 配置中心实现配置的动态管理,通过配置监听机制,使得应用能够实时感知配置变化并更新数据库连接等关键参数。总体来说,文章系统地阐释了 Nacos 如何以简洁而高效的方式实现服务治理与动态配置管理,帮助开发者降低微服务运维复杂度,构建更加稳定、弹性和高效的云原生系统。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【后端开发】系统设计101——Devops,Git与CICD,云服务与云原生,Linux,安全性,案例研究(30张图详解)

【后端开发】系统设计101——Devops&#xff0c;Git与CICD&#xff0c;云服务与云原生&#xff0c;Linux&#xff0c;安全性&#xff0c;案例研究&#xff08;30张图详解&#xff09; 文章目录 1、DevopsDevOps与SRE与平台工程的区别是什么&#xff1f;什么是k8s&#xff08;Ku…

100天精通Python(爬虫篇)——第113天:爬虫基础模块之urllib详细教程大全

文章目录 1. urllib概述2. urllib.request模块 1. urllib.request.urlopen()2. urllib.request.urlretrieve()3. urllib.request.Request()4. urllib.request.install_opener()5. urllib.request.build_opener()6. urllib.request.AbstractBasicAuthHandler7. urllib.request.…

win32汇编环境,结构体的使用示例一

;运行效果 ;win32汇编环境,结构体的使用示例一 ;举例说明结构体的定义&#xff0c;如何访问其中的成员&#xff0c;使用assume指令指向某个结构体&#xff0c;利用偏移得到成员值等 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>…

opencv:基于暗通道先验(DCP)的内窥镜图像去雾

目录 项目大体情况 暗通道先验&#xff08;Dark Channel Prior, DCP&#xff09;原理 项目代码解析 该项目是由我和我导师与舟山某医院合作开发的一个基于暗通道先验&#xff08;Dark Channel Prior&#xff0c;DCP&#xff09;的内窥镜图像去雾方法。具体来说&#xff0c;…

Java 大视界 -- Java 大数据在智能政务中的应用与服务创新(78)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

【DeepSeek】DeepSeek概述 | 本地部署deepseek

目录 1 -> 概述 1.1 -> 技术特点 1.2 -> 模型发布 1.3 -> 应用领域 1.4 -> 优势与影响 2 -> 本地部署 2.1 -> 安装ollama 2.2 -> 部署deepseek-r1模型 1 -> 概述 DeepSeek是由中国的深度求索公司开发的一系列人工智能模型&#xff0c;以其…

数据库,数据表的增删改查操作

一.数据库的基本操作 &#xff08;1&#xff09;创建数据库 创建数据库就是在数据库系统中划分一块存储数据的空间&#xff0c;方便数据的分配、放置和管理。在MySQL中使用CREATE DATABASE命令创建数据库&#xff0c;语法格式如下: CREATE DATABASE数据库名称; 注&#xff1a…

书籍《新能源汽车动力电池安全管理算法设计》和《动力电池管理系统核心算法》脑图笔记

目录 一、阅读背景二、《新能源汽车动力电池安全管理算法设计》脑图笔记三、《动力电池管理系统核心算法》脑图笔记四、后记参考学习 一、阅读背景 如今身处新能源动力电池行业&#xff0c;欲对动力电池相关算法做一些了解&#xff0c;通过查找相关电子书app&#xff0c;最后找…

激活函数篇 03 —— ReLU、LeakyReLU、RandomizedLeakkyReLU、PReLU、ELU

本篇文章收录于专栏【机器学习】 以下是激活函数系列的相关的所有内容: 一文搞懂激活函数在神经网络中的关键作用 逻辑回归&#xff1a;Sigmoid函数在分类问题中的应用 整流线性单位函数&#xff08;Rectified Linear Unit, ReLU&#xff09;&#xff0c;又称修正线性单元&a…

Python Pandas(3):DataFrame

1 介绍 DataFrame 是 Pandas 中的另一个核心数据结构&#xff0c;类似于一个二维的表格或数据库中的数据表。它含有一组有序的列&#xff0c;每列可以是不同的值类型&#xff08;数值、字符串、布尔型值&#xff09;。DataFrame 既有行索引也有列索引&#xff0c;它可以被看做由…

【C++高并发服务器WebServer】-14:Select详解及实现

本文目录 一、BIO模型二、非阻塞NIO忙轮询三、IO多路复用四、Select()多路复用实现 明确一下IO多路复用的概念&#xff1a;IO多路复用能够使得程序同时监听多个文件描述符&#xff08;文件描述符fd对应的是内核读写缓冲区&#xff09;&#xff0c;能够提升程序的性能。 Linux下…

算法兵法全略(译文)

目录 始计篇 谋攻篇 军形篇 兵势篇 虚实篇 军争篇 九变篇 行军篇 地形篇 九地篇 火攻篇 用间篇 始计篇 算法&#xff0c;在当今时代&#xff0c;犹如国家关键的战略武器&#xff0c;也是处理各类事务的核心枢纽。算法的世界神秘且变化万千&#xff0c;不够贤能聪慧…

瑞芯微 Rockchip 系列 RK3588 主流深度学习框架模型转成 rknn 模型教程

前言 在瑞芯微 Rockchip 芯片上进行 NPU 推理&#xff0c;需要先将模型文件转换成 rknn 模型文件&#xff0c;才能执行各种推理任务。本文将介绍如何安装各种工具&#xff0c;并最终实现将各种深度学习框架的模型文件转换成 rknn 文件。 本教程不仅适合 RK3588 平台&#xff…

STM32的HAL库开发---高级定时器---互补输出带死区实验

一、互补输出简介 互补输出&#xff1a;OCx输出高电平&#xff0c;则互补通道OCxN输出低电平。OCx输出低电平&#xff0c;则互补通道OCxN输出高电平。 带死区控制的互补输出&#xff1a;OCx输出高电平时&#xff0c;则互补通道OCxN过一会再输出输出低电平。这个时间里输出的电…

git提交到GitHub问题汇总

1.main->master git默认主分支是maser&#xff0c;如果是按照这个分支名push&#xff0c;GitHub会出现两个branch&#xff0c;与预期不符 解决方案&#xff1a;更改原始主分支名为main git config --global init.defaultBranch main2.git&#xff1a;OpenSSL SSL_read: SS…

【图片合并转换PDF】如何将每个文件夹下的图片转化成PDF并合并成一个文件?下面基于C++的方式教你实现

医院在为患者进行诊断和治疗过程中&#xff0c;会产生大量的医学影像图片&#xff0c;如 X 光片、CT 扫描图、MRI 图像等。这些图片通常会按照检查时间或者检查项目存放在不同的文件夹中。为了方便医生查阅和患者病历的长期保存&#xff0c;需要将每个患者文件夹下的图片合并成…

vite + axios 代理不起作用 404 无效

vite axios 代理不起作用 先看官方示例 export default defineConfig({server: {proxy: {// 字符串简写写法/foo: http://localhost:4567,// 选项写法/api: {target: http://jsonplaceholder.typicode.com,changeOrigin: true,rewrite: (path) > path.replace(/^\/api/, )…

Spring Boot接入Deep Seek的API

1&#xff0c;首先进入deepseek的官网&#xff1a;DeepSeek | 深度求索&#xff0c;单击右上角的API开放平台。 2&#xff0c;单击API keys&#xff0c;创建一个API&#xff0c;创建完成务必复制&#xff01;&#xff01;不然关掉之后会看不看api key&#xff01;&#xff01;&…

Windows 系统下使用 Ollama 离线部署 DeepSeek - R1 模型指南

引言 随着人工智能技术的飞速发展&#xff0c;各类大语言模型层出不穷。DeepSeek - R1 凭借其出色的语言理解和生成能力&#xff0c;受到了广泛关注。而 Ollama 作为一款便捷的模型管理和部署工具&#xff0c;能够帮助我们轻松地在本地环境中部署和使用模型。本文将详细介绍如…

Python+Flask搭建属于自己的B站,管理自己电脑里面的视频文件。支持对文件分类、重命名、删除等操作。

适用场景 个人用户:管理本地图片和视频文件,快速查找和分类。 团队协作:共享文件分类标签,提升团队文件管理效率。 教育机构:用于教学资源管理,方便教师和学生查找资料。 企业应用:作为内部文件管理系统,支持批量操作和分类管理。 功能介绍 文件浏览与播放:用户可以浏…