Spring Cloud Alibaba(三、Nacos配置中心)

之前一直引入携程的Apollo做配置中心使用。但Apollo比较重,需自己运维很多组件。半年前发现Nacos配置管理易用。支持配置热更新,支持命名空间。本文使用Nacos Config Starter完成Spring Cloud应用的配置管理。本质是通过Nacos替代application.yml本地配置文件,用法也是@Value("${user.name}")注解给变量赋值。

Nacos配置管理模型几个概念

对于Nacos配置管理,通过Namespace、group、Data ID能够定位到一个配置集。

数据定义层次

  1. 配置集(Data ID)
    在系统中,一个配置文件通常就是一个配置集,一个配置集可以包含了系统的各种配置信息,例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。每个配置集都可以定义一个有意义的名称,就是配置集的ID即DataID。

  2. 配置项
    配置集中包含的一个个配置内容就是配置项。它代表一个具体的可配置的参数与其值域,通常以 key=value 的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR) 就是一个配置项。

  3. 配置分组(Group)
    配置分组是对配置集进行分组,通过一个有意义的字符串(如 Buy 或 Trade )来表示,不同的配置分组下可以有相同的配置集(Data ID)。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:可用于区分不同的项目或应用,例如:学生管理系统的配置集可以定义一个group为:STUDENT_GROUP。

  4. 命名空间(Namespace)
    命名空间(namespace)可用于进行不同环境的配置隔离。例如可以隔离开发环境、测试环境和生产环境,因为它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过namespace隔离。不同的命名空间下,可以存在相同名称的配置分组(Group) 或 配置集。

模型层次详解

Nacos抽象定义了Namespace、Group、Data ID的概念,具体这几个概念代表什么,取决于我们把它们看成什么,这里推荐给大家一种用法,如下图:

对应关系

对应关系:

配置模型 对应项目
Namespace 代表不同环境,如:开发、测试、生产环境。
Group 代表某项目,如:XX金融项目、XX电商项目
DataId 每个项目下往往有若干个工程,每个配置集(DataId)是一个工程的主配置文件

使用说明

获取配置集需要:

  1. nacos服务地址,必须指定
  2. namespace,如不指定默认public
  3. group,如不指定默认DEFAULT_GROUP
  4. dataId,必须指定

代码实践

参考上篇文章新建Module

Spring Initializr创建项目

选择Nacos Configuration依赖

  1. POM文件引入Nacos Config Starter。注:IDEA工具的向导自动生成POM有问题,参考我修改后的POM文件。
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.pay.springcloud.alibaba</groupId>
    <artifactId>nacos-config</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>nacos-config</name>
    <description>Nacos config project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
    </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-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  1. 在应用的 /src/main/resources/新增bootstrap.yml 配置文件,用来配置 Nacos Config 元数据。bootstrap.yml从配置中心拉取Nacos动态配置,其他的配置可再读取application.yml。如果相同属性application.yml值会覆盖bootstrap.yml定义的值,bootstrap.yml文件内容:
server:
  port: 8081
spring:
  application:
    name: nacos-config-client
  profiles:
    active: dev #指定开发环境
  cloud:
    nacos:
      config:
        server-addr: localhost:8848 #服务器地址
        group: bankProject #指定配置群组 --如果是Public组,则可以省略群组配置
        prefix: guoxiuzhiPrefix #Data ID 前缀 -- 如果没有配置则默认为 ${spring.appliction.name}
        file-extension: yml #指定文件后缀,yaml格式的配置

命名约定:
Data ID =${spring.cloud.nacos.config.prefix}.${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} 最终拼接出来的就是:guoxiuzhiPrefix-dev.yml (一定要注意约定!)
Group = ${spring.cloud.nacos.config.group}
spring.cloud.nacos.config.prefix默认为spring.application.name的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。

说明:

  • spring.profile.active 即为当前环境对应的 profile,注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成${prefix}.${file-extension}
  • file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension来配置。支持 properties 和 yaml 类型。

在nacos上新建配置文件

根据上面规则, Data ID配置如下:

配置信息

调用配置信息

Controller代码

package com.pay.springcloud.alibaba.nacosconfig.nacosconfig;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName:  SampleController
 * @Description: Nacos配置信息动态读取
 * @author: 郭秀志 jbcode@126.com
 * @date:   2020/6/13 18:30
 * @Copyright:
 */
@RestController
@RefreshScope
public class SampleController {

    @Value("${user.name}")
    String userName;

    @Value("${user.age:25}")
    int age;

    @RequestMapping("/user")
    public String simple() {
        return "Hello Nacos Config!" + "Hello " + userName + " " + age + "!";
    }
}
  • 通过 Spring Cloud 原生注解@RefreshScope实现配置自动更新,这是controller中加这个注解的原因。

测试

  1. 访问url:http://localhost:8080/user
    返回:Hello Nacos Config!Hello 郭秀志 40!
  2. 修改Nacos的配置,name修改为郭秀志(Oliver),age修改为43,并点击发布按钮。
  3. 再次访问url:http://localhost:8080/user
    返回:Hello Nacos Config!Hello 郭秀志(Oliver) 43!。可见配置属性已经被代码动态识别。

Namespace来区分环境

上面是通过激活哪个配置文件来调用不同环境的配置信息。
profiles.active: dev对应要建Data ID是guoxiuzhiPrefix-dev.yml,如果生产环境要建guoxiuzhiPrefix-prod.yml 。

Data ID区分环境

前面提到了Nacos的Namespace概念,他就是为不同环境,如:开发、测试、生产环境而生。接下来我们采用Namespace来区分不同环境的配置。

  1. 创建多套namespace。


    3个环境的命名空间
  2. 注释激活属性文件配置
profiles:
    #active: dev #指定开发环境
  1. DEV、TEST、PROD3个空间分别添加配置信息
    TEST环境信息配置

    为了区分返回值,其他两个环境配置内容稍不同:
user:
  name: guo from DEV
  age: 2
user:
  name: guo from PROD
  age: 3
  1. 指定使用的名称空间。
    bootstrap.yml完整内容
server:
  port: 8081
spring:
  application:
    name: nacos-config-client
  profiles:
    #active: dev #指定开发环境
  cloud:
    nacos:
      config:
        server-addr: localhost:8848 #服务器地址
        #namespace 注意这里是nacos生成的Namespace ID 字符串而不是DEV
        namespace: 5e476dab-9ae9-4626-bdab-f065f12196d3
        group: bankProject #指定配置群组 --如果是Public命名空间 则可以省略群组配置
        prefix: guoxiuzhiPrefix #文件名 -- 如果没有配置则默认为 ${spring.appliction.name}
        file-extension: yml #指定文件后缀,yml格式的配置

说明:namespace值是nacos生成的“Namespace ID ”字符串,而不是命名空间名称“DEV”

Namespace ID

  1. 测试
    访问url:http://localhost:8080/user
    返回:Hello Nacos Config!Hello guo from DEV 2!
    证明已经取了DEV命名空间的相关配置。

基于Namespace的Jekins部署或手动发包

切换环境时,只需更改namespace即可。

原启动参数:--spring.profiles.active=dev
需要替换参数为:--spring.cloud.nacos.config.namespace=5e476dab-9ae9-4626-bdab-f065f12196d3

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342