Nacos学习笔记 分布式应用配置管理

Posted 鮀城小帅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nacos学习笔记 分布式应用配置管理相关的知识,希望对你有一定的参考价值。

1. 发布配置

首先在nacos发布配置,我们规划了两个服务service1、service2,并且想对这两个服务的配置进行集中维护。
浏览器访问 http://127.0.0.1:8848/nacos ,打开nacos控制台,并点击菜单配置管理->配置列表:Nacos添加如下的配置:

service1:

Namespace: 394d9bcf-5aed-4315-8037-ae40f9cd6a4f #开发环境
Data ID: service1.yaml
Group : TEST_GROUP
配置格式: YAML
配置内容: common:
name: service1 config

新建配置

 service2

Namespace: 394d9bcf-5aed-4315-8037-ae40f9cd6a4f #开发环境
Data ID: service2.yaml
Group : TEST_GROUP
配置格式: YAML
配置内容: common:
name: service2 config

 新建配置

 2. 创建父工程

为了规范依赖的版本,这里创建父工程,指定依赖的版本。

父工程pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>nacos-config</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. 微服务 service1  配置

Spring Cloud Alibaba Nacos ConfifigSpring Cloud应用中集成Nacos,通过Spring cloud 原生方式快捷的获取配置内容。

Spring Cloud是什么:

Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot的开发风格做到一键启动和部署。 Spring Cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,集成最多的组件要属 Netflflix 公司,通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
Spring Cloud Alibaba Nacos Confifig 是什么:
Spring Cloud Alibaba Nacos Discovery Spring Cloud Alibaba 的子项目,而 Spring Cloud Alibaba 是阿里巴巴公司提供的开源的基于 Spring cloud 的微服务套件合集,它致力于提供微服务开发的一站式解决方案,可以理解为 spring cloud 是一套微服务开发的 标准 , spring cloud alibaba spring cloud Netflflix 是实现。使用 Spring Cloud Alibaba 方案,开发者只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。

dsf由于Nacos是阿里的中间件,因此,若开发Spring cloud微服务应用,使用Spring Cloud Alibaba Nacos Confifig集成Nacos的配置管理功能是比较明智的选择。

(1)  新建项目 service1

首先新增一个名为service1工程,并添加group ID com.alibaba.cloud artifact ID spring-cloudstarter-alibaba-nacos-config starter

    <parent>
        <artifactId>nacos-config</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.config</groupId>
    <artifactId>service1</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

(2) bootstrap.yml配置

一般来说,spring boot的配置将在application.yml(也可以是application.properties)文件中编写,由于使用外部配置中心,必须将原先的application.yml重命名为bootstrap.ymlbootstrap.yml如下所示:

spring.cloud.nacos.confifig.server-addr 指定了Nacos Server的网络地址和端口号

server:
  port: 56010 #启动端口 命令行注入

spring:
  application:
    name: service1
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848  # 配置中心地址
        file-extension: yaml
        namespace: 394d9bcf-5aed-4315-8037-ae40f9cd6a4f   # 开发环境
        group: TEST_GROUP  # 测试组

地方以上配置文件说明该应用将从地址为127.0.0.1:8848配置中心获取配置,通过以下信息定位配置集:

namespace:394d9bcf-5aed-4315-8037-ae40f9cd6a4f # 开发环境
group:TEST_GROUP # 测试组
Data Id:service1.yaml
Note spring-cloud-starter-alibaba-nacos-confifig 在加载配置的时候,加载了以 dataid $spring.application.name.$file - extension:properties 的基础配置。对应以上的配置,它会去nacos server 中加载 data id service1.yaml 配置集
Note: 若没有指定 spring.cloud.nacos.confifig.group 配置 , 则默认为 DEFAULT_GROUP

(3) 启动配置客户端

新增Spring Boot 启动类,并增加获取配置的web访问端点/confifigs,通过标准的spring @Value 方式。

package com.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * @author wushaopei
 * @create 2022-12-23 18:36
 */
@SpringBootApplication
@RestController
public class Service1Bootstrap 

    public static void main(String[] args) 
        SpringApplication.run(Service1Bootstrap.class,args);
    

    @Value("$common.name")
    private String config1;

    @GetMapping(value = "/configs")
    public String getConfig1()
        return config1;
    

4. 微服务 service2 配置

service2的创建流程与service1一致:

需要注意的是spring boot 启动端口要避免重复,spring.application.nameservice2

server:
  port: 56020 #启动端口 命令行注入

spring:
  application:
    name: service2
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848  # 配置中心地址
        file-extension: yaml
        namespace: 394d9bcf-5aed-4315-8037-ae40f9cd6a4f   # 开发环境
        group: TEST_GROUP  # 测试组

分别启动service1service2项目,并分别访问 /confifigs进行测试,不同项目能够获取各自的配置内容。

5. 支持配置的动态更新

基于上面快速上手的例子,若要实现配置的动态更新,只需要进行如下改造:

package com.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author wushaopei
 * @create 2022-12-23 18:57
 */
@SpringBootApplication
@RestController
public class Service2Bootstrap 

    public static void main(String[] args) 
        SpringApplication.run(Service2Bootstrap.class,args);
    

    // 注入配置文件上下文
    @Autowired
    private ConfigurableApplicationContext applicationContext;

    @GetMapping(value = "/configs")
    public String getConfigs()
        return applicationContext.getEnvironment().getProperty("common.name");
    

我们通过nacos控制台更新common.name的配置值,再次访问web端点/confifigs,发现应用程序能够获取到最新的配置值,说明spring-cloud-starter-alibaba-nacos-confifig 支持配置的动态更新。

Note 可以通过配置 spring.cloud.nacos.confifig.refresh.enabled=false 来关闭动态刷新

6. 自定义 namespace 与 group 配置

支持自定义 namespace的配置

在没有明确指定 $spring.cloud.nacos.config.namespace 配置的情况下,默认使用的是 Nacos Public 这个namespace。如果需要使用自定义的命名空间,可以通过以下配置来实现:

spring:
    cloud:
        nacos:
            config:
                namespace: b3404bc0‐d7dc‐4855‐b519‐570ed34b62d7

Note:该配置必须放在 bootstrap.yml文件中。此外 spring.cloud.nacos.config.namespace 的值是 namespace对应的 idid 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespae,否则将会导致读取不到正确的配置。

支持自定义 Group 的配置

在没有明确指定 $spring.cloud.nacos.config.group 配置的情况下,默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现:

spring:
    cloud:
        nacos:
            config:
                group: DEVELOP_GROUP

Note:该配置必须放在 bootstrap.properties 文件中。并且在添加配置时 Group 的值一定要和spring.cloud.nacos.config.group 的配置值一致。

7.自定义扩展的 Data Id 配置

Spring Cloud Alibaba Nacos Confifig可支持自定义 Data Id 的配置。 一个完整的配置案例如下所示:

下边我们在service2微服务下配置扩展。

spring:
  application:
    name: service2
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848  # 配置中心地址
        file-extension: yaml
        namespace: 394d9bcf-5aed-4315-8037-ae40f9cd6a4f   # 开发环境
        group: TEST_GROUP  # 测试组
# config external configuration
# 1. Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
        ext-config[0]:
            data-id: ext-config-common01.properties
# 2. Data Id 不在默认的组,不支持动态刷新
        ext-config[1]:
          data-id: ext-config-common02.properties
          group: GLOBALE_GROUP
# 3. Data Id 既不在默认的组,也支持动态刷新
        ext-config[2]:
          data-id: ext-config-common03.properties
          group: REFRESH_GROUP
          refresh: true
        enabled: false

可以看到:

  • 通过 spring.cloud.nacos.config.ext-config[n].data-id 的配置方式来支持多个 Data Id 的配置。
  • 通过 spring.cloud.nacos.config.ext-config[n].group 的配置方式自定义 Data Id 所在的组,不明确配置的话,默认是 DEFAULT_GROUP
  • 通过 spring.cloud.nacos.config.ext-config[n].refresh 的配置方式来控制该 Data Id 在配置变更时,是否支持应用中可动态刷新,感知到最新的配置值。默认是不支持的。
Note spring.cloud.nacos.config.ext - config[n].data - id 的值必须带文件扩展名,文件扩展名既可支持 properties ,又可以支持 yaml/yml 。 此时 spring.cloud.nacos.config.file - extension 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。

通过自定义扩展的 Data Id 配置,既可以解决多个应用间配置共享的问题,又可以支持一个应用有多个配置文件。

测试:

配置ext-confifig-common01.properties

 配置ext-confifig-common02.properties

  配置ext-confifig-common03.properties

 

    @GetMapping(value = "/configs2")
    public String getConfigs2()
        String name = applicationContext.getEnvironment().getProperty("common.name");
        String age = applicationContext.getEnvironment().getProperty("common.age");
        String address = applicationContext.getEnvironment().getProperty("common.address");
        String birthday= applicationContext.getEnvironment().getProperty("common.birthday");
        String fullname = applicationContext.getEnvironment().getProperty("common.fullname");
        return name+"+"+ age+"+"+address+"+"+ birthday+"+"+ fullname;
    

重启应用,访问http://localhost:56011/confifigs2,观察配置是否成功获取。输出:

service2 config+12+beijing+1990‐1‐1+zhangsansanff

8. 自定义共享 Data Id 配置

为了更加清晰的在多个应用间配置共享的 Data Id ,你可以通过以下的方式来配置:

spring:
  cloud:
    nacos:
      config:
        shared-dataids: ext-config-common01.properties,ext-config-common02.properties
        refreshable-dataids: ext-config-common01.properties

可以看到:

  • 通过 spring.cloud.nacos.config.shared-dataids 来支持多个共享 Data Id 的配置,多个之间用逗号隔开。
  • 通过 spring.cloud.nacos.config.refreshable-dataids 来支持哪些共享配置的 Data Id 在配置变化时,应用中是否可动态刷新,感知到最新的配置值,多个 Data Id 之间用逗号隔开。如果没有明确配置,默认情况下所有共享配置的 Data Id 都不支持动态刷新。

Note:通过 spring.cloud.nacos.config.shared-dataids 来支持多个共享配置的 Data Id 时,多个共享配置间的一个优先级的关系我们约定:按照配置出现的先后顺序,即后面的优先级要高于前面

Note :通过 spring.cloud.nacos.config.shared - dataids 来配置时, Data Id 必须带文件扩展名,文件扩展名既可支持 properties ,也可以支持 yaml/yml 。 此时 spring.cloud.nacos.config.file - extension 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
Note spring.cloud.nacos.config.refreshable - dataids 给出哪些需要支持动态刷新时, Data Id 的值也必须明确给出文件扩展名。

测试输出:

service2 config+12+beijing+null+null

为什么后边两个值为null?

共享DataId的配置使用默认的groupDEFAULT_GROUPext-confifig-common02.properties不属于DEFAULT_GROUP

共享DataId的配置相比扩展的 Data Id 配置,它把group固定为DEFAULT_GROUP,建议使用扩展的 Data Id 置,因为扩展的 Data Id 配置也可以实现共享DataId配置。

9. 配置的优先级

Spring Cloud Alibaba Nacos Confifig 目前提供了三种配置能力从 Nacos 拉取相关的配置。

  • A: 通过 spring.cloud.nacos.config.shared-dataids 支持多个共享 Data Id 的配置
  • B: 通过 spring.cloud.nacos.config.ext-config[n].data-id 的方式支持多个扩展 Data Id 的配置,多个Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.ext-config[n].data-id 其中 n 的值越大,优先级越高。
  • C: 通过内部相关规则(应用名、扩展名 )自动生成相关的 Data Id 配置

当三种方式共同使用时,他们的一个优先级关系是:C > B >A

测试,屏蔽共享dataId,放开ext-confifig,如下:

server:
  port: 56020 #启动端口 命令行注入

spring:
  application:
    name: service2
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848  # 配置中心地址
        file-extension: yaml
        namespace: 394d9bcf-5aed-4315-8037-ae40f9cd6a4f   # 开发环境
        group: TEST_GROUP  # 测试组
#        shared-dataids: ext-config-common01.properties,ext-config-common02.properties
#        refreshable-dataids: ext-config-common01.properties
# config external configuration
# 1. Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
        ext-config[0]:
            data-id: ext-config-common01.properties
# 2. Data Id 不在默认的组,不支持动态刷新
        ext-config[1]:
          data-id: ext-config-common02.properties
          group: GLOBALE_GROUP
# 3. Data Id 既不在默认的组,也支持动态刷新
        ext-config[2]:
          data-id: ext-config-common03.properties
          group: REFRESH_GROUP
          refresh: true
        enabled: false

修改ext-confifig-common03.properties

输出:

service2 config aaa+15+beijing+1990‐1‐1+zhangsansanff

通过测试发现多个 Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.ext-config[n].data-id .

其中 n 的值越大,优先级越高。

修改:service1.yaml

 输出:

service2 config aaa+25+beijing+1990‐1‐1+zhangsansanff

通过测试发现:BC同时存在,C优先级高。

10. 完全关闭配置

通过设置 spring.cloud.nacos.confifig.enabled = false 来完全关闭 Spring Cloud Nacos Config.

以上是关于Nacos学习笔记 分布式应用配置管理的主要内容,如果未能解决你的问题,请参考以下文章

Nacos学习笔记 Nacos的简介与安装

分布式架构之Nacos注册&配置中心搭建

SpringCloud微服务:阿里开源组件Nacos,服务和配置管理

分布式注册中心-Nacos

nacos入门配置学习

SpringCloud微服务:阿里开源组件Nacos,服务和配置管理