之前一直引入携程的
Apollo
做配置中心使用。但Apollo
比较重,需自己运维很多组件。半年前发现Nacos
配置管理易用。支持配置热更新,支持命名空间。本文使用Nacos Config Starter
完成Spring Cloud
应用的配置管理。本质是通过Nacos
替代application.yml
本地配置文件,用法也是@Value("${user.name}")
注解给变量赋值。
Nacos配置管理模型几个概念
对于Nacos配置管理,通过Namespace、group、Data ID
能够定位到一个配置集。
配置集(Data ID)
在系统中,一个配置文件通常就是一个配置集,一个配置集可以包含了系统的各种配置信息,例如,一个配置集可能包含了数据源、线程池、日志级别等配置项。每个配置集都可以定义一个有意义的名称,就是配置集的ID即DataID。配置项
配置集中包含的一个个配置内容就是配置项。它代表一个具体的可配置的参数与其值域,通常以 key=value 的形式存在。例如我们常配置系统的日志输出级别(logLevel=INFO|WARN|ERROR) 就是一个配置项。配置分组(Group)
配置分组是对配置集进行分组,通过一个有意义的字符串(如 Buy 或 Trade )来表示,不同的配置分组下可以有相同的配置集(Data ID)。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:可用于区分不同的项目或应用,例如:学生管理系统的配置集可以定义一个group为:STUDENT_GROUP。命名空间(Namespace)
命名空间(namespace)可用于进行不同环境的配置隔离。例如可以隔离开发环境、测试环境和生产环境,因为它们的配置可能各不相同,或者是隔离不同的用户,不同的开发人员使用同一个nacos管理各自的配置,可通过namespace隔离。不同的命名空间下,可以存在相同名称的配置分组(Group) 或 配置集。
模型层次详解
Nacos抽象定义了Namespace、Group、Data ID
的概念,具体这几个概念代表什么,取决于我们把它们看成什么,这里推荐给大家一种用法,如下图:
对应关系:
配置模型 | 对应项目 |
---|---|
Namespace | 代表不同环境,如:开发、测试、生产环境。 |
Group | 代表某项目,如:XX金融项目、XX电商项目 |
DataId | 每个项目下往往有若干个工程,每个配置集(DataId)是一个工程的主配置文件 |
使用说明
获取配置集需要:
-
nacos
服务地址,必须指定 -
namespace
,如不指定默认public
-
group
,如不指定默认DEFAULT_GROUP
-
dataId
,必须指定
代码实践
参考上篇文章新建Module
。
- 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>
- 在应用的 /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中加这个注解的原因。
测试
- 访问url:
http://localhost:8080/user
。
返回:Hello Nacos Config!Hello 郭秀志 40!
。 - 修改Nacos的配置,name修改为
郭秀志(Oliver)
,age修改为43
,并点击发布按钮。
- 再次访问url:
http://localhost:8080/user
。
返回:Hello Nacos Config!Hello 郭秀志(Oliver) 43!
。可见配置属性已经被代码动态识别。
Namespace来区分环境
上面是通过激活哪个配置文件来调用不同环境的配置信息。
profiles.active: dev
对应要建Data ID是guoxiuzhiPrefix-dev
.yml,如果生产环境要建guoxiuzhiPrefix-prod
.yml 。
前面提到了Nacos的
Namespace
概念,他就是为不同环境,如:开发、测试、生产环境而生。接下来我们采用Namespace
来区分不同环境的配置。
-
创建多套namespace。
- 注释激活属性文件配置
profiles:
#active: dev #指定开发环境
-
DEV、TEST、PROD
3个空间分别添加配置信息
为了区分返回值,其他两个环境配置内容稍不同:
user:
name: guo from DEV
age: 2
user:
name: guo from PROD
age: 3
- 指定使用的名称空间。
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”
。
- 测试
访问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