Nacos 配置管理菜单
配置文件的 id 构成同服务 id 的构成,也是由三部分: namespace、group、data id
组成。不同的是第三部分的服务名在配置文件中更名为了 data id。(为了方便,我们使用单节点的 Nacos Server 进行演示)
命名的最佳实践
- namespace:不同的开发环境,如:dev、test、prod
- group:不同的项目名称,如:XX 电商项目,XX 金融项目
- data id:项目下具体业务微服务节点的名称,微服务节点的的主配置文件
克隆
比如我们想要基于 test 命名空间的配置文件,在创建一个另外的命名空间,克隆功能可以帮助我们快速完成这个操作,还可以对选中的配置文件进行重命名克隆:
历史版本
即对一个配置文件的多次修改进行记录,可以进行回滚以及对比。
监听查询
列出有哪些 Nacos Client 业务节点使用该配置文件,并实时监听配置修改。也就是说,Nacos 可以实现 Nacos 管控台修改配置同步最新值到业务节点本地配置的功能。具体可以在 Nacos Client 上进行配置 refresh 属性是否为 true 来启用该功能。
延展配置文件与共享配置文件
我已经提前创建好了五个配置文件:
- nacos-service
- extension-config-0
- extension-config-1
- mysql-config
- redis-config
可以分为三类:
- 服务的主配置文件:nacos-service
- 服务的扩展配置文件:extension-config-*
- 多服务间共享的配置文件:mysql-config、redis-config
扩展与共享配置文件都是需要被引入的其他配置文件,二者只是语义不同。比如共享配置文件,可以为 mysql、redis、rocketMQ 等等其他数据库或中间件的配置文件。扩展配置文件,可以为具体类别项目的扩展配置,可以将一些业务上的配置放到该类配置文件中。无论如何,仅是作为语义的区分。
服务节点接入 Nacos 配置中心
当创建好远端配置文件后,我们在 Nacos Client 业务服务节点中进行引入。因为接入配置中心属于系统级别的配置,所以我们在 bootstrap.yaml
中进行配置:
spring:
cloud:
nacos:
# 通用配置
# server-addr: 127.0.0.1:8000 # 1. nacos 集群服务地址
server-addr: 127.0.0.1:8100 # 1. nacos 服务地址
username: nacos
password: nacos
# 服务治理
discovery:
namespace: 0298b122-a60d-47f5-9be3-9ea149f17185
group: DEFAULT_GROUP
service: nacos-service
cluster-name: nacos-service-cluster
weight: 1
# 服务配置
config:
# 1. 主配置
namespace: 0298b122-a60d-47f5-9be3-9ea149f17185
name: nacos-service # 默认为 ${spring.application.name}
group: DEFAULT_GROUP
file-extension: yaml # 不可写在 data-id 上,必须手动声明
refresh-enabled: true # 动态刷新配置值
# 2. 共享配置
shared-configs:
- data-id: mysql-config
group: DEFAULT_GROUP
refresh: true
file-extension: yaml
- data-id: redis-config
group: DEFAULT_GROUP
refresh: true
file-extension: yaml
# 3. 延展配置
extension-configs:
- data-id: extension-config-0
group: DEFAULT_GROUP
refresh: true
file-extension: yaml
- data-id: extension-config-1
group: DEFAULT_GROUP
refresh: true
file-extension: yaml
- data-id
- group
- refresh:Nacos 管控台修改配置文件的配置时,立即刷新最新值到到业务节点
- file-extension: 文件后缀
可以发现一个问题:不能跨命名空间的引入其他配置文件。因为在引入延展、共享配置文件的配置项中,不存在主配置文件中的配置项 namespace
。可以看下具体的配置项源码:
public void setExtensionConfigs(List<Config> extensionConfigs) {
this.extensionConfigs = extensionConfigs;
}
public static class Config {
/**
* the data id of extended configuration.
*/
private String dataId;
/**
* the group of extended configuration, the default value is DEFAULT_GROUP.
*/
private String group = "DEFAULT_GROUP";
/**
* the suffix of nacos config dataId, also the file extension of config content.
*/
private String fileExtension;
/**
* whether to support dynamic refresh, the default does not support .
*/
private boolean refresh = false;
}
多个配置文件的优先级
下面,我们看下配置文件中的内容:
- extension-config-0、extension-config-1、mysql-config、redis-config 的配置文件中都只有一个配置项:
test-key: xxx
,值分别为:extendsion0、extendsion1、mysql、redis
- 主配置文件 nacos-service(也有配置项:
test-key
):
server:
port: 6300
logging:
level:
root: info
spring:
mvc:
path-match:
matching-strategy: ANT_PATH_MATCHER
application:
name: nacos-service
test-key: nacos-service-test-key
通过这个 test-key 的取值来测试多个配置文件的优先级:
@SpringBootApplication
public class NacosServiceApplication {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext context = SpringApplication.run(NacosServiceApplication.class, args);
ConfigurableEnvironment environment = context.getEnvironment();
while (true) {
String testKey = environment.getProperty("test-key");
System.out.println(testKey);
TimeUnit.SECONDS.sleep(2);
}
}
}
测试结果如下:
- 不同类别的配置文件间:主配置文件 > 延展配置文件 > 共享配置文件
- 同类别的多个配置文件间:索引值大的配置文件会覆盖索引值小的配置文件中的相同配置项,即后配置的会覆盖先前配置的。比如共享配置中的 redis-config 与 mysql-config 的相同配置项 test-key,最终会取:redis
本地配置覆盖 Nacos 远端的配置
有时我们期望本地的bootstrap.yaml
或application.yaml
的某些配置的优先级高于 Nacos Server 远端配置文件中的相同配置项,即最终以本地的配置为主,该如何配置呢?在远端的 Nacos 配置文件中添加:
spring:
cloud:
config:
override-none: true
allow-override: true
override-system-properties: false
注意,必须是在 Nacos 远端的配置文件中添加。在本地的 bootstrap.yaml 文件中添加是不生效的!
@RefreshScope
作用:当 Nacos 管控台修改配置文件的配置时,立即刷新 Bean 实例中通过 @Value 注解注入的配置属性值。即解决 @Value 注解注入的值后续不能动态刷新的问题。
@SpringBootApplication
public class NacosServiceApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(NacosServiceApplication.class, args);
}
@RestController
@RefreshScope
public class RefreshScopeController {
@Value("${test-key}")
private String testKey;
@GetMapping(value = "/refreshScope")
public String refreshScope() {
return String.format("Latest value : %s ", testKey);
}
}
}