Spring Cloud Alibaba's configuration management component - Nacos

[TOC]


Use Nacos Configuration Management

Why need configuration management?

In the micro-service architecture, each micro-services are likely to be multiple instances, in order to ensure that the contents of the configuration file of the same micro different instances of the same service, we need to have a service that can be centrally managed micro-services project profiles, usually we call it unified configuration management center. Because if the contents of the configuration file is inconsistent, it may lead to differences in the different instances of the same micro-services take place in behavior, resulting in some errors.

In addition, enterprise development projects also require the use of different configurations in different environments, and enables dynamic refresh the configuration file without restarting the service, in order to fulfill these requirements we have to use the unified configuration management center

At present the industry's more popular unified configuration management component has Spring Cloud Center of Config, Spring Cloud Alibaba and Ctrip open source of Nacos Apollo. This paper describes Nacos configuration management center used as a single, on the other central component configuration and basic use Nacos can refer to the following articles:

Next, we look at how to use Nacos manage configuration files, and now I have some interface code as follows:

@RestController
@RequiredArgsConstructor
public class TestController {

    @Value("${your.configuration}")
    private String yourConfiguration;

    @GetMapping("/getConfiguration")
    public String getConfiguration(){
        return yourConfiguration;
    }
}

This code reads a configuration item, configuration item exists in this case the project application.ymlfile, as follows:

your:
  configuration: your_value

So how do we use Nacos manage this configuration? First, the need for the project to integrate Nacos configuration management functions, add the following dependence in pom.xml file:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
  • Tips: the Spring Cloud version of the project is to use Greenwich.SR1the version of Alibaba2.1.0.RELEASE

Then resourcescreate a new directory named bootstrap.ymlfiles, add the following configuration items:

spring:
  cloud:
    nacos:
      config:
        # 指定作为配置中心的nacos server地址
        server-addr: 127.0.0.1:8848
        # 配置文件格式
        file-extension: yaml
      discovery:
        # 指定作为服务注册中心的nacos server地址
        server-addr: 127.0.0.1:8848
  application:
    name: content-center
  profiles:
    active: dev

To "Configuration List" Nacos the administration page of the new configuration:
Spring Cloud Alibaba's configuration management component - Nacos

FIG new configuration as follows:
Spring Cloud Alibaba's configuration management component - Nacos

注意,这里的Data ID是具有一定格式的,需要与项目中的配置对应上。如上图中的:content-center-dev.yaml,其中content-center是微服务名称,dev是环境,yaml是配置文件的格式。这里简单整理成了一张对照图,如下:
Spring Cloud Alibaba's configuration management component - Nacos

  • Tips:这里文件Data ID的后缀不一定必须是.yaml,也可以是.yml,因为这两种后缀其实都是表示同一种文件格式

到目前为止,我们就已经为项目整合了Nacos的配置管理功能,并在Nacos Server上新建了项目所需的配置。此时就可以将之前配置在application.yml文件中的配置项给删除掉。然后启动项目,访问/getConfiguration接口,返回结果如下则代表整合成功:
Spring Cloud Alibaba's configuration management component - Nacos


动态刷新配置及回滚

在实际的企业开发中,我们通常希望在配置中心上修改了配置项后,不需要重启项目就能够实现实时的动态配置刷新。对于整合了Nacos的微服务项目来说,想要实现这个功能是很简单的,只需要在读取了配置属性的类上加上@RefreshScope注解即可。如下示例:

// 该注解用于标识哪些地方需要动态刷新配置,可以写在类及方法上
@RefreshScope
@RestController
@RequiredArgsConstructor
public class TestController {

    @Value("${your.configuration}")
    private String yourConfiguration;

    @GetMapping("/getConfiguration")
    public String getConfiguration(){
        return yourConfiguration;
    }
}

添加完该注解后,重启项目,然后到Nacos上修改之前配置项的值,点击发布后会有一个内容比较的提示,可以看到我将之前的your_value改成了my_value
Spring Cloud Alibaba's configuration management component - Nacos

点击确认发布后,然后再访问/getConfiguration接口,返回的就是修改后的值了,而此时我们并没有重启项目:
Spring Cloud Alibaba's configuration management component - Nacos

除了以上所介绍的动态刷新之外,还有一个比较重要的功能:配置回滚。如果有一天修改某些配置项并发布后发现手滑改错了,导致项目运行出问题,那么就可以使用回滚功能可以帮助我快速回滚到某个特定的版本上。我们可以在Nacos的“历史版本”页面中查询指定配置的历史版本,如下图:
Spring Cloud Alibaba's configuration management component - Nacos

点击“详情”可以查看到具体的配置内容:
Spring Cloud Alibaba's configuration management component - Nacos

点击“回滚配置”则可以回滚到指定的历史版本,例如我这里就回滚到初始版本:
Spring Cloud Alibaba's configuration management component - Nacos

提示回滚成功后访问/getConfiguration接口,会发现报错了:
Spring Cloud Alibaba's configuration management component - Nacos

这是目前Nacos 1.1版本的一个Bug,当选择回滚的版本是最初版本时就会发生这个问题。官方称会在1.2版本中修复该问题,而我目前使用的是最新的1.1.3版本,仍属于1.1版本(2019-09-10),所以该bug还存在。相关的issues如下:

在1.1版本下,只要回滚的不是初始版本则不会触发这个bug,回滚其他版本是可以正常使用的,所以该问题注意一下即可规避

注:触发该bug后,配置内容由于回滚失败会丢失,此时需要重新创建配置


配置共享

以上我们介绍了Nacos作为配置中心的基本使用,而本小节将介绍相同应用下的配置共享,所谓的配置共享就是一些配置项可以在相同应用的不同环境中进行共享。

例如以上示例中的${your.configuration}配置项,我们希望在所有的环境下该配置项都是相同的值,而又不想在每个环境的配置文件里面都配置一遍,也就是说这个配置项是所有环境通用的,那么这时候就需要将该配置项在所有环境中共享了。

想要实现配置共享只需要新建一个配置文件即可,首先我们来看一段日志信息,当我们启动项目时,控制台会出输出如下一段日志信息:

2019-09-11 20:47:42.197  INFO 13778 --- [           main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='content-center-dev.yaml'}, NacosPropertySource {name='content-center.yaml'}]}

从该日志信息可以看到,项目在启动时会到Nacos上读取两个配置文件,即content-center-dev.yamlcontent-center.yaml,其中content-center-dev.yaml里保存的是开发环境下特定的配置,而content-center.yaml里保存的则是所有环境下通用的配置。项目在启动时具体读取哪个环境的配置文件是由bootstrap.yml文件中的spring.profiles.active配置项所决定的。

既然我们知道保存在content-center.yaml里的配置项会在所有环境中共享,那么只需要到Nacos上新建这个配置文件即可。如下示例:
Spring Cloud Alibaba's configuration management component - Nacos

新建完成后,修改项目中的spring.profiles.active为其他环境,然后重启项目,此时访问/getConfiguration接口,可以看到返回的是通用配置文件里所配置的值:
Spring Cloud Alibaba's configuration management component - Nacos

  • Tips:特定环境下的配置优先级高于通用环境配置,例如${your.configuration}配置项同时存在于content-center-dev.yamlcontent-center.yaml中,若spring.profiles.active的值为dev,那么读取的将是content-center-dev.yaml里所配置的值。

以上介绍了相同应用在不同环境下的配置共享,但如何实现不同应用之间的配置共享呢?例如我们经常会遇到微服务A和微服务B的数据库配置是一样的,如果能将这段相同的配置在这两个服务之间共享,那么就可以省去一些重复的工作。

目前Nacos提供了两种方式可以实现不同应用之间的配置共享,第一种方式是使用shared-dataids。接下来我们进行一个简单的演示,首先需要到Nacos上创建一些共享配置,如下示例:
Spring Cloud Alibaba's configuration management component - Nacos

其中common1.yaml配置内容如下:

common1:
  configuration1: common1_value

common2.yaml配置内容如下:

common2:
  configuration2: common2_value

创建共享配置完成后,修改项目中的bootstrap.yml文件如下:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
      config:
        # 指定共享配置的DataId,多个使用,分隔
        # 越靠后,优先级越高;common2.yml > common1.yaml
        # .yaml后缀不能少,目前只支持yaml/properties
        shared-dataids: common1.yaml,common2.yaml
        # 指定哪些共享配置支持动态刷新,多个使用,分隔
        refreshable-dataids: common1.yaml
        server-addr: 127.0.0.1:8848
        file-extension: yaml
  application:
    name: content-center
  profiles:
    active: dev

从以上的配置示例可以看出,其实shared-dataids的主要作用就是用来指定共享配置的Data ID,使得该微服务可以读取这些共享配置。同理,其他微服务若想读取这些共享配置,只需在项目的bootstrap.yml文件中添加相应的shared-dataids配置即可,如此一来就实现了多个微服务之间的配置共享。

然后我们来写两个简单的接口验证一下是否能正常读取这两个共享配置的值,代码如下:

@RefreshScope
@RestController
@RequiredArgsConstructor
public class TestController {

    @Value("${common1.configuration1}")
    private String common1Configuration;

    @Value("${common2.configuration2}")
    private String common2Configuration;

    @GetMapping("/getCommonConfiguration1")
    public String getCommonConfiguration1() {
        return common1Configuration;
    }

    @GetMapping("/getCommonConfiguration2")
    public String getCommonConfiguration2() {
        return common2Configuration;
    }
}

启动项目,访问结果如下:
Spring Cloud Alibaba's configuration management component - Nacos
Spring Cloud Alibaba's configuration management component - Nacos


第二种方式也是差不多的,只不过使用的配置项是ext-config,修改项目中的bootstrap.yml文件如下:

spring:
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yaml
        ext-config:
          # 需共享的DataId,yaml后缀不能少,目前只支持yaml/properties
          # 越靠后,优先级越高 优先级common2.yaml > common1.yaml
          - data-id: common1.yaml
            # common1.yaml所在的group
            group: DEFAULT_GROUP
            # 是否允许刷新,默认false
            refresh: true
          - data-id: common2.yaml
            group: DEFAULT_GROUP
            refresh: true
  application:
    name: content-center
  profiles:
    active: dev

ext-config提供了较为细化的配置方式,并且可以指定配置组。到目前为止,我们介绍了三种从Nacos上读取配置的方式,其优先级如下:

shared-dataids < ext-config < 自动

除此之外,当存在相同的远程配置和本地配置时,远程配置优先级要高于本地配置文件。但可以通过添加如下配置调整,需要注意的是这段配置需要放在远程配置才会生效:

spring:
  cloud:
    config:
      # 是否允许本地配置覆盖远程配置,默认true
      allow-override: true
      # 是否一切以本地配置为准,默认false
      override-none: false
      # 系统环境变量或系统属性才能覆盖远程配置文件的配置
      # 本地配置文件中配置的优先级低于远程配置,默认true
      override-system-properties: true

为什么要使用bootstrap.yml

在介绍为项目整合Nacos做配置管理服务的时候,示例里将Nacos Config的相关配置都写在一个bootstrap.yml文件里,但是为什么要使用bootstrap.yml呢?使用application.yml不可以吗?

这是其实是因为bootstrap.yml会被优先读取,也就是说如果项目里同时存在一个bootstrap.yml和一个application.yml的话,那么bootstrap.yml将会优先于application.yml被Spring Boot读取。这样才能实现连接外部的配置管理服务器,从远程读取一些必要的配置,避免项目在启动时缺失必要配置项而导致启动失败。

这里实际涉及到一个引导上下文的概念,它是ApplicationContext的父上下文,并且是由Spring Cloud提供的, 它所在的位置如下图所示:
Spring Cloud Alibaba's configuration management component - Nacos

引导上下文在prepareEnvironment的阶段就会被创建,创建时会读取bootstrap.yml的内容作为引导配置, 因此bootstrap.yml优先于application.yml加载。引导上下文与操作系统的引导程序非常类似,而bootstrap.yml就相当于设置引导程序的相关指令。


关于Nacos的数据持久化

Nacos会将数据持久化到本地,当Nacos作为服务发现组件时,默认会将服务的注册信息存储在如下目录中:

类Unix系统:~/nacos/naming
windows系统:C:\用户\{用户名}\nacos\naming

具体文件如下图所示:
Spring Cloud Alibaba's configuration management component - Nacos

Open one of the files, you can see the service registration information in the following format:

{
    "metadata": {},
    "dom": "DEFAULT_GROUP@@content-center",
    "cacheMillis": 10000,
    "useSpecifiedURL": false,
    "hosts": [],
    "name": "DEFAULT_GROUP@@content-center",
    "checksum": "f797b857f5312a616a875924ecf6481a",
    "lastRefTime": 1564815242804,
    "env": "",
    "clusters": ""
}

When Nacos as a distribution center, will be divided into two and the configuration data is stored in two places, one of which is stored in the embedded derby database, which is the Apache open source written entirely by Java embedded database, while derby there will be a data directory, as follows:

$NACOS_HOME/data/derby-data

We can use the IDEA connection derby to view the data sheet and store content related to the right of the menu bar, point to open the Database -> click on the + sign to add a database connection -> Data Source -> Apache Derby. As shown below:
Spring Cloud Alibaba's configuration management component - Nacos

Notice that you need to Nacos Server to stop off, otherwise it is not connected. After stopping Nacos Server, fill in the connection information, Path is filled derby data directory, the default user and password are nacos. As shown below:
Spring Cloud Alibaba's configuration management component - Nacos

Once connected, data can be seen in Table derby follows:
Spring Cloud Alibaba's configuration management component - Nacos

Wherein the CONFIG_INFOtable stores the configuration data, the open form can be seen as follows:
Spring Cloud Alibaba's configuration management component - Nacos

Note that the derby and can not be used in a production environment, because it is an embedded database, can not achieve high availability and cluster deployment, it is generally available at the time to build a production Nacos will instead use MySQL database and other non-embedded database.

The following data is stored in another directory, mainly because some snapshots of data:

类Unix系统:~/nacos/config
windows系统:C:\用户\{用户名}\nacos\config

Snapshot mainly used to improve performance and to make disaster recovery, specific documents as shown below:
Spring Cloud Alibaba's configuration management component - Nacos

Guess you like

Origin blog.51cto.com/zero01/2437931