nacos 配置中心详解(有这一篇就够啦)

前言

本文主要学习和使用 nacos 配置中心,从 ncaos 配置中心原理出发,深入到个人项目中的nacos配置中心使用。 应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数据库连接参数、启动参数等。应用程序根据配置改变自身的行为,但一般程序不会去修改配置。

对于配置,大家在日常开发中应该很熟悉。配置的加载有多种方式,其中hard code在应用中的方式最不可取的,而配置文件、环境变量、启动参数、甚至数据库的方式,在微服务架构中多机器、多应用、多实例的情况下也有很大不足,会使得配置分散,不易于管理。想象一下,如果你启动了一个服务的多个实例,一旦配置需要更改,在没有配置中心的情况,你得将每个实例的配置信息改一遍,这将是非常繁琐且低效的工作。

配置中心就是一种统一管理各种应用配置的基础服务组件,它将将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去管理配置。

一个合格的配置中心需要满足如下特性: • 配置项容易读取和修改 • 分布式环境下应用配置的可管理性,即提供远程管理配置的能力 • 支持对配置的修改的检视以把控风险 • 可以查看配置修改的历史记录 不同部署环境下应用配置的隔离性

nacos 基本配置信息

在这里,我们手动实现对 nacos 配置的相关操作,对后续的配置化理解有很大帮助。 首先要了解几个 Nacos 的关键信息:

nameSpace:命名空间,默认public,标识不同执行环境;如:dev,test,prod ... group :组标识,默认DEFAULT_GROUP,标识不同项目;如:ORDER_GROUP,USER_GROUP ... DataId:文件唯一标识,简单理解为文件名(在同组中唯一)。 如:dev_ORDER_GROUP_application.yaml -> dev环境_订单项目_ application.yaml配置文件

配置中心使用原理

基础依赖 ------ nacos 客户端

java 复制代码
<dependency>
  	<groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>1.1.3</version>
</dependency>
java 复制代码
 public static void main(String[] args) throws NacosException, InterruptedException, UnsupportedEncodingException {
        //使用nacos open api 服务获取相关配置
        //namespace 区分命名空间(dev,test...)
        String nameSpacePublic = "";         //命名空间区分配置所属环境(或多用户配置)
        String nameSpaceDev = "76c8c145-bdc0-4bfc-965d-80337b21cdbf"; //命名空间区分配置所属环境(或多用户配置)
        String nameSpaceTest = "766363ce-8b26-4882-b1d9-e12134d5cad7"; //命名空间区分配置所属环境(或多用户配置)
        String nameSpaceProd = "d1888d9a-9911-4b6a-84ac-a689cd4c7c66";//命名空间区分配置所属环境(或多用户配置)
        String group = "DEFAULT_GROUP";   //组标识可以区分不同的项目
        String dataId = "nacos-config-demo.yaml";  //配置文件唯一标识

        String nacosIp = "127.0.0.1"; //nacso 服务地址
        String nacosPort = "8848"; //nacos 服务端口

        Properties properties = new Properties();  // nacos配置信息
        properties.put("serverAddr",nacosIp+":"+nacosPort);
        properties.put("namespace",nameSpaceDev);


        //链接nacos
        ConfigService configService = NacosFactory.createConfigService(properties);
        //获取配置  5000 超时时间
        String config = configService.getConfig(dataId, group, 5000);

        System.out.println(config);

        //监听,当服务端配置改变时主动推送到客户端
        configService.addListener(dataId, group, new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }

            //当配置变化时获取通知
            @Override
            public void receiveConfigInfo(String s) {
                System.out.println("配置变化");
                System.out.println(s);
            }
        });
        // 测试让主线程不退出,因为订阅配置是守护线程,主线程退出守护线程就会退出。 正式代码中无需下面代码

        while (true){
            Thread.sleep(2000);
        }
    }

测试结果如下

这样,我们就能实现对 nacos 中配置的获取以及实时监听 相关配置的改变。 在 springboot 配置化实现nacos 基本原理如上。

SpringBoot + nacos 配置中心

1. 引入依赖

java 复制代码
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>

2.关于nacos配置存放位置

注意:nacos 配置需要配置到 bootstrap.yml 或 bootstrap.properties 文件中,而不能是application.yml/properties 文件。

在 SpringBoot 启动时对自定义配置文件有如下加载顺序:

  1. bootstrap.yml(或bootstrap.properties)优先加载。这个文件用于应用程序的引导阶段,通常包含系统级别的一些参数配置,这些参数一般是不变的。
  2. bootstrap.yml(或bootstrap.properties)由父Spring ApplicationContext加载,而父ApplicationContext被加载到使用application.yml(或application.properties)的之前。
  3. application.yml(或application.properties)随后加载。这个文件通常用来定义单个应用级别的配置,如果搭配Spring Cloud Config使用,可以定义动态替换的文件。
  4. application.yml(或application.properties)由当前的Spring ApplicationContext加载。

需要注意的是,一旦bootstrap.yml被加载,其内容不会被覆盖,即便后期加载的application.yml 的内容标签与bootstrap.yml的标签一致,application.yml也不会覆盖bootstrap.yml。而application.yml里面的内容可以动态替换。

综上所述,加载顺序为:bootstrap.yml(或bootstrap.properties)优先加载,然后是bootstrap.yml(或bootstrap.properties),接着是application.yml(或application.properties),最后是application.yml(或application.properties)。这样的加载顺序允许基础设施配置先于应用程序配置加载,并且允许后面加载的配置覆盖先前加载的配置。

综上所述:Nacos 配置文件必须放入到 bootstrap 文件中,如果放在 application 文件中会出现nacos 连接失败等初始化问题,导致系统无法正常启动。(简单理解为系统已经在加载 Application 配置了,但发现这些配置还没有。)

3. springBoot Nacos 配置

java 复制代码
spring:
  application:
    name: prod-service
  profiles:
    active: dev
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848,127.0.0.1:18848 #配置中心地址(集群)
        file-extension: yaml   #文件后缀  项目名+文件后缀 -》指定文件
        namespace: d31a3f74-e122-41b3-b36e-0de805587fb3  #配置的环境(dev环境)
        ext-config[0]:  #额外的配置文件
          data-id: testExt.properties
          group: TEST_GROUP #所在组 不填则默认
          refresh: true  #是否支持动态刷新
        ext-config[1]:
          data-id: nacos-demo.yaml
        ext-config[2]:
          data-id: application.yaml  #将相关配置内容放到 nacos 服务器上,读取就行
          group: TEST_GROUP
          refresh: true

#配置加载的优先级-命名冲突
# 1 基础的和扩展的存在命名冲突 - 以基础的为准
# 2 扩展的之间存在命名冲突 - ext-config[n] n的值越大优先级越高

配置文件解读:

server-addr :服务地址,可以是多个。nacos 集群启动需要修改nacos 启动方式。 file-extension :文件后缀。在搜索文件时会自动与服务名拼接成一个 dataId; namespace:命名空间 group:组 ext-configx:扩展配置 shared-configsx:(本配置未使用) 共享配置

在此配置文件中一共会加载 5 个配置文件,分别是:

配置文件 来源 说明
prod-service.yaml {application.name}.{file-extension} 绝对会获取的配置
prod-service-dev.yaml {application.name}-{profiles.active}.{file-extension} profiles.active 存在时获取
testExt.properties ext-config0 扩展配置
nacos-demo.yaml ext-config1 扩展配置
application.yaml ext-config2 扩展配置

说明:profiles.active 在本文中特意赋值为 dev。在这里需要和 namespace 的dev环境做区分,此处的 dev 仅会与服务名生成 prod-service-dev.yaml 配置。而并不能跨 namespace 去 namespace - dev 中获取。

3.ext-configx 与 shared-configsx

ext-configx 与 shared-configsx 使用方法相同 都包含:data-id、group(默认为字符串DEFAULT_GROUP)、refresh(默认为true) 三个属性。 -refresh:是动态刷新,在Nacos修改配置后,服务可以动态感知而无需重启项目。

4.配置优先级

在不同配置文件中如果存在相同的配置项,优先级高的匹配文件会覆盖优先级低的。 相关配置优先级如下。

  • userservice-dev.yml(当前环境配置profiles) > userservice.yml(nacos上的)> application.yml(本地的)
  • 主配置 > 扩展配置(extension-configs) > 共享配置(shared-configs)。
  • 同为扩展配置,存在如下优先级关系:extension-configs3 > extension-configs2 > extension-configs1 > extension-configs0
  • 同为共享配置,存在如下优先级关系:shared-configs3 > shared-configs2 > shared-configs1 > shared-configs0

简单记为:定位越明确优先级越高,远程的优先级大于本地,数组编号越大优先级越高

相关推荐
fanly112 天前
Surging AI Agent 完整产品介绍
微服务·microservice
蝎子莱莱爱打怪9 天前
XZLL-IM干货系列 04|Netty 长连接实战:Pipeline 怎么排、心跳怎么跳、连接怎么管
后端·微服务·面试
SamDeepThinking10 天前
Java微服务练习方式
java·后端·微服务
米丘13 天前
微前端之 Web Components 完全指南
微服务·html
霸道流氓气质15 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
霸道流氓气质16 天前
Spring Boot 微服务性能优化完全指南
spring boot·微服务·性能优化
地瓜伯伯16 天前
从MESI缓存一致性协议讲透synchronized的底层
java·spring boot·spring·spring cloud·微服务·springcloud
Devin~Y16 天前
大厂 Java 面试实录:从音视频内容社区到 AI RAG 的全链路技术设计
java·spring boot·redis·spring cloud·微服务·kafka·音视频
递归尽头是星辰16 天前
AI 访问数据仓库:从直连到微服务化
数据仓库·人工智能·微服务·dataagent·ai数据治理
就改了16 天前
Windows 环境 SkyWalking 完整实操教程
windows·微服务·skywalking