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-config[x]:扩展配置 shared-configs[x]:(本配置未使用) 共享配置

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

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

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

3.ext-config[x] 与 shared-configs[x]

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

4.配置优先级

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

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

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

相关推荐
qq_171538851 天前
利用Spring Cloud Gateway Predicate优化微服务路由策略
android·javascript·微服务
科技互联人生1 天前
微服务常用的中间件及其用途
微服务·中间件·系统架构
小蜗牛慢慢爬行1 天前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
小扳1 天前
微服务篇-深入了解 MinIO 文件服务器(你还在使用阿里云 0SS 对象存储图片服务?教你使用 MinIO 文件服务器:实现从部署到具体使用)
java·服务器·分布式·微服务·云原生·架构
DT辰白2 天前
如何解决基于 Redis 的网关鉴权导致的 RESTful API 拦截问题?
后端·微服务·架构
老猿讲编程2 天前
技术发展历程:从 CORBA 到微服务
微服务·云原生·架构
time_silence2 天前
微服务——服务通信与接口设计
微服务
Java程序之猿3 天前
微服务分布式(一、项目初始化)
分布式·微服务·架构
Yvemil73 天前
《开启微服务之旅:Spring Boot Web开发举例》(一)
前端·spring boot·微服务