概述
Nacos是阿里在2018年发布的集服务发现、动态配置等功能为一体的开源产品。下文将会围绕Nacos对配置中心需要的各功能进行讲解。
1.Nacos配置概念
命名空间
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
配置集 ID
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
配置分组
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
2.快速启动Nacos
在https://github.com/alibaba/nacos/releases根据当前环境下载对应的包,解压压缩包,根据实际情况修改配置,如果没有对db进行配置,Nacos会默认使用内嵌数据库Derby。
新建自己的命名空间
新建我们的配置集
通过https://nacos.io/zh-cn/docs/open-api.html提供的api查询我们的配置是否添加成功
3.Nacos Client
我会基于Nacos提供的demo来进行讲解
引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
3.1 获取配置
添加配置
spring:
cloud:
nacos:
config:
server-addr: 172.16.0.11:8848 # Nacos 服务器地址
namespace: 2a05557f-1077-4274-9074-4623e603ac85 # 使用的 Nacos 的命名空间,默认为 null
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: tf-auth-dev # 使用的 Nacos 配置集的 dataId
file-extension: yml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties
spring.cloud.nacos.config.server-addr Nacos 服务器地址
spring.cloud.nacos.config.namespace 配置命名空间,使用默认控制不需要配置,如果使用自建的命名空间需要配置命名空间的命名空间id
spring.cloud.nacos.config.group 配置分组,默认为 DEFAULT_GROUP
spring.cloud.nacos.config.name 配置文件名字,即data-id
spring.cloud.nacos.config.file-extension 配置文件对应的格式,在新建的时候设置,默认PROPERTIES
nacos-test-one.yml
nacos:
test:
one: one
访问代码
package com.kenho.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ValueController {
@Value("${nacos.test.one}")
private String one;
@RequestMapping("one")
public void one()
{
System.out.println("nacos.test.one:"+one);
}
}
启动
2021-03-25 23:43:42.628 INFO 1427 --- [ main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: 'nacos-test-one.yml', group: 'DEFAULT_GROUP'
2021-03-25 23:43:42.630 INFO 1427 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='nacos-test-one.yml'}]}
输出
nacos.test.one:one
3.2 多组配置
添加配置
spring:
cloud:
nacos:
config:
server-addr: 172.16.0.11:8848 # Nacos 服务器地址
namespace: da1c5f3b-7ab5-4461-a251-1abf7a03b85e # 使用的 Nacos 的命名空间,默认为 null
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
sharedDataids: nacos-test-one.yml,nacos-test-two.yml
file-extension: yml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties
spring.cloud.nacos.config.sharedDataids 一个分组下的多个配置,以逗号隔开
nacos-test-two.yml
nacos:
test:
two: two
访问代码
package com.kenho.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ValueController {
@Value("${nacos.test.one}")
private String one;
@Value("${nacos.test.two}")
private String two;
@RequestMapping("one")
public void one()
{
System.out.println("nacos.test.one:"+one);
}
@RequestMapping("two")
public void two()
{
System.out.println("nacos.test.two:"+two);
}
}
启动
2021-03-25 23:59:59.921 INFO 1621 --- [ main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: 'nacos-test-one.yml', group: 'DEFAULT_GROUP'
2021-03-25 23:59:59.930 INFO 1621 --- [ main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: 'nacos-test-two.yml', group: 'DEFAULT_GROUP'
2021-03-25 23:59:59.939 INFO 1621 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='null.yml'}, NacosPropertySource {name='nacos-test-two.yml'}, NacosPropertySource {name='nacos-test-one.yml'}]}
输出
nacos.test.one:one
nacos.test.two:two
3.3 多分组配置
添加配置
spring:
cloud:
nacos:
config:
server-addr: 172.16.0.11:8848 # Nacos 服务器地址
namespace: da1c5f3b-7ab5-4461-a251-1abf7a03b85e # 使用的 Nacos 的命名空间,默认为 null
file-extension: yml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties
ext-config:
- dataId: nacos-test-one.yml
group: DEFAULT_GROUP
- dataId: nacos-test-other.yml
group: OTHER_GROUP
spring.cloud.nacos.config..ext-config.dataId[0] 不同分组环境配置的dataid
spring.cloud.nacos.config..ext-config.group[0] 不同分组环境配置的分组
nacos-test-other.yml
nacos:
test:
other: other
访问代码
package com.kenho.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ValueController {
@Value("${nacos.test.one}")
private String one;
@Value("${nacos.test.other}")
private String other;
@RequestMapping("one")
public void one()
{
System.out.println("nacos.test.one:"+one);
}
@RequestMapping("other")
public void two()
{
System.out.println("nacos.test.other:"+other);
}
}
启动
2021-03-26 00:12:34.169 INFO 1737 --- [ main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: 'nacos-test-one.yml', group: 'DEFAULT_GROUP'
2021-03-26 00:12:34.174 INFO 1737 --- [ main] o.s.c.a.n.c.NacosPropertySourceBuilder : Loading nacos data, dataId: 'nacos-test-other.yml', group: 'OTHER_GROUP'
2021-03-26 00:12:34.179 INFO 1737 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='null.yml'}, NacosPropertySource {name='nacos-test-other.yml'}, NacosPropertySource {name='nacos-test-one.yml'}]}
输出
nacos.test.one:one
nacos.test.other:other
4.版本回滚
首先Nacos的版本有自己的版本回滚概念,参考https://github.com/alibaba/nacos/issues/4064,如下图所示你只可以回滚当前版本之前的版本
5.自动刷新
Nacos官方github提供的例子的自动刷新是有问题的 注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。具体查看https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明
添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
添加配置
ext-config:
- dataId: nacos-test-one.yml
group: DEFAULT_GROUP
refresh: true
- dataId: nacos-test-other.yml
group: OTHER_GROUP
refresh: true
spring.cloud.nacos.config..ext-config.refresh[0] 设置该配置组是否自动刷新,在当前版本中的依赖默认是false的
拓展信息
通过查看源码NacosPropertySourceLocator生成NacosPropertySource的逻辑可知道,除了loadApplicationConfiguration方法对标spring.cloud.nacos.config.namespace,spring.cloud.nacos.config.group ,spring.cloud.nacos.config.name ,spring.cloud.nacos.config.file-extension 生成的对象是默认自动刷新。而loadSharedConfiguration方法和loadExtConfiguration方法生成的对象默认却是false的,所以要根据实际需要对对应配置进行进行刷新设置。
public PropertySource<?> locate(Environment env) {
nacosConfigProperties.setEnvironment(env);
ConfigService configService = nacosConfigManager.getConfigService();
if (null == configService) {
log.warn("no instance of config service found, can't load config from nacos");
return null;
}
long timeout = nacosConfigProperties.getTimeout();
nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService,
timeout);
String name = nacosConfigProperties.getName();
String dataIdPrefix = nacosConfigProperties.getPrefix();
if (StringUtils.isEmpty(dataIdPrefix)) {
dataIdPrefix = name;
}
if (StringUtils.isEmpty(dataIdPrefix)) {
dataIdPrefix = env.getProperty("spring.application.name");
}
CompositePropertySource composite = new CompositePropertySource(
NACOS_PROPERTY_SOURCE_NAME);
loadSharedConfiguration(composite);
loadExtConfiguration(composite);
loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);
return composite;
}
对需要刷新的配置的类设置@RefreshScope注解
package com.kenho.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class ValueController {
@Value("${nacos.test.one}")
private String one;
@Value("${nacos.test.other}")
private String other;
@RequestMapping("one")
public void one()
{
System.out.println("nacos.test.one:"+one);
}
@RequestMapping("other")
public void two()
{
System.out.println("nacos.test.other:"+other);
}
}
更新配置刷新服务配置日志
2021-03-29 22:08:59.128 INFO 12054 --- [51-1abf7a03b85e] c.a.n.client.config.impl.ClientWorker : [fixed-172.16.0.11_8848-da1c5f3b-7ab5-4461-a251-1abf7a03b85e] [polling-resp] config changed. dataId=nacos-test-one.yml, group=DEFAULT_GROUP, tenant=da1c5f3b-7ab5-4461-a251-1abf7a03b85e
2021-03-29 22:08:59.129 INFO 12054 --- [51-1abf7a03b85e] c.a.n.client.config.impl.ClientWorker : get changedGroupKeys:[nacos-test-one.yml+DEFAULT_GROUP+da1c5f3b-7ab5-4461-a251-1abf7a03b85e]
2021-03-29 22:08:59.142 INFO 12054 --- [51-1abf7a03b85e] c.a.n.client.config.impl.ClientWorker : [fixed-172.16.0.11_8848-da1c5f3b-7ab5-4461-a251-1abf7a03b85e] [data-received] dataId=nacos-test-one.yml, group=DEFAULT_GROUP, tenant=da1c5f3b-7ab5-4461-a251-1abf7a03b85e, md5=b63f4defc2ca8f5cdd5cbd80a15fa1b8, content=nacos:
test:
one: oneone, type=yaml
2021-03-29 22:08:59.143 INFO 12054 --- [51-1abf7a03b85e] c.a.nacos.client.config.impl.CacheData : [fixed-172.16.0.11_8848-da1c5f3b-7ab5-4461-a251-1abf7a03b85e] [notify-context] dataId=nacos-test-one.yml, group=DEFAULT_GROUP, md5=b63f4defc2ca8f5cdd5cbd80a15fa1b8
2021-03-29 22:08:59.352 WARN 12054 --- [51-1abf7a03b85e] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[null.yml] & group[DEFAULT_GROUP]
2021-03-29 22:08:59.352 INFO 12054 --- [51-1abf7a03b85e] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-null.yml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-test-other.yml,OTHER_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-nacos-test-one.yml,DEFAULT_GROUP'}]
2021-03-29 22:08:59.353 INFO 12054 --- [51-1abf7a03b85e] o.s.boot.SpringApplication : No active profile set, falling back to default profiles: default
2021-03-29 22:08:59.361 INFO 12054 --- [51-1abf7a03b85e] o.s.boot.SpringApplication : Started application in 0.217 seconds (JVM running for 107.666)
2021-03-29 22:08:59.370 INFO 12054 --- [51-1abf7a03b85e] o.s.c.e.event.RefreshEventListener : Refresh keys changed: [nacos.test.one]
2021-03-29 22:08:59.370 INFO 12054 --- [51-1abf7a03b85e] c.a.nacos.client.config.impl.CacheData : [fixed-172.16.0.11_8848-da1c5f3b-7ab5-4461-a251-1abf7a03b85e] [notify-ok] dataId=nacos-test-one.yml, group=DEFAULT_GROUP, md5=b63f4defc2ca8f5cdd5cbd80a15fa1b8, listener=com.alibaba.cloud.nacos.refresh.NacosContextRefresher$1@7edffae3
2021-03-29 22:08:59.370 INFO 12054 --- [51-1abf7a03b85e] c.a.nacos.client.config.impl.CacheData : [fixed-172.16.0.11_8848-da1c5f3b-7ab5-4461-a251-1abf7a03b85e] [notify-listener] time cost=227ms in ClientWorker, dataId=nacos-test-one.yml, group=DEFAULT_GROUP, md5=b63f4defc2ca8f5cdd5cbd80a15fa1b8, listener=com.alibaba.cloud.nacos.refresh.NacosContextRefresher$1@7edffae3
6.配置加密
查看官方问答地址https://nacos.io/zh-cn/docs/faq.html,目前为止暂时还不支持官方提供的配置加密功能,只能靠 sdk 做好了加密再存到 nacos 中。
添加依赖
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>1.16</version>
</dependency>
添加配置
jasypt:
encryptor:
password: stephanie #根密码
nacos-test-one.yml
nacos:
test:
one: ENC(9PO2acQm5wpRqNV6oBXZ+w==)
输出
nacos.test.one:oneone
原生的动态刷新对配置加密支持不支持,目前应该只能支持密码等私密信息进行加密。
参考:https://nacos.io/zh-cn/docs/concepts.html
github:https://github.com/tale2009/Distributed-Learning/tree/main/NacosConfig-Learning