Nacos 配置中心介绍及使用
前言
传统的配置方式弊端
1、维护性:一旦有服务配置发生变化,所有的服务配置都得改变,例如 mysql、redis、mq 等。
2、实效性:修改完服务后还得重启,频繁的修改意味着频繁的重启,重启完成之后配置修改才会生效。
3、安全性:配置的一些远程 IP 地址,用户名和密码等敏感信息都会暴露。
Nacos提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,可以在 Nacos Server 集中管理 Spring Cloud应用的外部属性配置。
springcloud config 对比
三大优势
- springcloud config 大部分场景结合git使用,动态变更还需要依赖 Spring Cloud Bus 消息总线来通过所有的客户端变化.
- springcloud config 不提供可视化界面
- nacos config 使用长轮询更新配置,一旦配置有变动后,通知 Provider 的过程非常的迅速,从速度上秒杀 springcloud 原来的 config 几条街
对比项目/配置中心 | springcloud config | apollo | nacos |
---|---|---|---|
开源时间 | 2014.9 | 2016.5 | 2018.6 |
配置实时推送 | 支持(Spring Cloud Bus) | 支持(Http 长轮询 1s 内) | 支持(Http 长轮询 1s 内) |
版本管理 | 支持(Git) | 自动管理 | 自动管理 |
配置回滚 | 支持(Git) | 支持 | 支持 |
灰度发布 | 支持 | 支持 | 支持 |
权限管理 | 支持 | 支持 | 支持 |
多集群多环境 | 支持 | 支持 | 支持 |
监听查询 | 支持 | 支持 | 支持 |
多语言 | 只支持 Java | Go,C++,Python,java,.NET,OpenApi | Python,Java,Nodejs,OpenApi |
分布式高可用最小集群数量 | Conifig-Server2+Git+MQ | Config2+Admin3+portal*2+Mysql=8 | Nacos*3+Mysql=4 |
配置格式校验 | 不支持 | 支持 | 支持 |
通行协议 | HTTP 和 AMQP | HTTP | HTTP |
数据一致性 | Git保证数据一致性,Config-Server从Git读取数据 | 数据库模拟消息队列,Apollo定时读取消息 | HTTP 异步通知 |
单机读(tps) | 7(限流所致) | 9000 | 15000 |
单机写 | 5(限流所致) | 1100 | 1800 |
3 节点读 | 21(限流所致) | 27000 | 45000 |
3 节点写 | 5(限流所致) | 3300 | 5600 |
一、Nacos-Config 配置界面
1.1、配置列表
新建配置文件
实际上是将配置保存到数据库中
1.2、历史版本
当发布配置更新之后
可以看到历史版本
1.3、监听查询
可以查看配置是否推动更新成功。
1.4、克隆
可以将配置快速克隆到其它开发环境中
二、权限控制
如果需要使用权限控制,需要修改配置文件
$ vim application.properties
### If turn on auth system:
nacos.core.auth.enabled=true
此时可以看到多了权限控制模块,可以给不同的用户分配不同的角色,给不同的角色分配不同资源的不同的权限,下图为例,test 用户只能访问 dev 环境,且无法进行添加操作。
二、Nacos 配置中心使用
最佳实践:
Namespace:代表不同的环境,如开发,测试,生产等
Group:代表项目,如xxx安全项目,xxx电商项目等
DataId:每个项目往往有若干个工程(微服务),每个配置集(DataId)是一个工程(微服务)的主配置文件
2.1、引入依赖
先配置中心有这样一份配置
<!--Nacos config 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2.2、启动类如下
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) throws InterruptedException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ConfigApplication.class, args);
while (true) {
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" + userName + "; age: " + userAge);
TimeUnit.SECONDS.sleep(5);
}
}
}
在运行之前,必须使用 bootstrap.properties 配置文件来配置 Nacos Server 地址,此配置文件是 springcloud 扩展出来的,例如
resource 下 bootstrap.yml 文件内容如下
spring:
application:
# 会自动根据服务名称拉取 dataid 对应的配置,如果 dataid 与服务名不一致,需要手动指定 dataid
name: com.hudu.mall.order.redis
cloud:
nacos:
server-addr: 192.168.33.62:8847
username: test
password: 123456
config:
namespace: public
成功获取到配置信息
当我们修改配置文件之后,nacos 可以立马监测到配置的修改。
三、其它扩展
3.1、nacos 配置文件拓展名
spring:
application:
# 会自动根据服务名称拉取 dataid 对应的配置,如果 dataid 与服务名不一致,需要手动指定 dataid
name: com.hudu.mall.order.redis
cloud:
nacos:
server-addr: 192.168.33.62:8847
username: kunjuee
password: we753951.
config:
namespace: public
# nacos 客户端默认是 properties 的文件扩展名
# 一旦修改成了飞 Properties 格式,则必须通过 file-extension 进行设置
file-extension: yaml
3.2、支持配置的动态更新
即上面演示的,当配置中心的配置修改后,会立马监测到配置文件的修改。
可以通过spring.cloud.nacos.config.refresh-enabled=false
来关闭动态刷新
3.3、支持 profile 粒度的配置
spring-cloud-starter-alibaba-nacos-config 在加载配置的时候,不仅仅加载了以 dataid 为 ${spring.application.name}.${file-extension:properties}
为前缀的基础配置,还加载了 dataid 为 ${spring.application.name}-${profile}.${file-extension:properties}
的基础配置。在日常开发中如果遇到多套配置环境下的不同配置,可以通过 Spring 提供的${spring.profile.active}
这个配置项来配置
spring.profiles.active=develop
注意:${spring.profile.active}
当通过配置文件来指定时必须放在 bootstrap.properties 文件中
当前配置中心配置如下
com.hudu.mall.order
内容如下
com.hudu.mall.order-dev.yaml
内容如下
项目结构如下
application.yml 内容如下
server:
port: 8050
# 在配置中心中,可以通过 profile 进行设置
# 只有默认的配置文件才能结合 profile 进行使用(跟服务名相同的 dataid 的配置文件,称之为默认的配置文件)
# 对应的 Dataid:${spring.application.name}-${profile}.${file-extension:properties}
# profile 的后缀必须与跟随默认配置文件的格式来
spring:
profiles:
active: dev
bootstrap.yml 文件内容如下
spring:
application:
# 会自动根据服务名称拉取 dataid 对应的配置,如果 dataid 与服务名不一致,需要手动指定 dataid
# 跟服务名相同的 dataid 的配置文件,称之为默认的配置文件)
# 除了默认的配置文件,其他配置文件必须写上后缀
name: com.hudu.mall.order
cloud:
nacos:
server-addr: 192.168.33.62:8847
username: kunjuee
password: we753951.
config:
namespace: public
# nacos 客户端默认是 properties 的文件扩展名
# 一旦修改成了飞 Properties 格式,则必须通过 file-extension 进行设置
file-extension: yaml
# 客户端将无法感知配置的变化
# refresh-enabled: false
结果如下
配置文件优先级(优先级大的会覆盖优先级小的,并且会形成互补)
profile > 默认配置文件
但是,还是推荐使用命名空间的方式区别不同环境的配置,因为可以进行权限控制
3.4、支持 namespace 的配置
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离, 例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
在没有明确指定$(spring.clpud.nacos.config.namespace}
配置的情况下,默认使用的是 Nacos 上Public 这个 namespace。如果需要使用自定义的命名空间,可以通过以下配置来实现:
spring.cloud.nacos.config.namespace=namespaceName
3.5、自定义 Group 的配置
在没有明确指定${spring.cloud.nacos.config.group}
配置的强况下,默认使用的是 DEFAULT_GROUP,如果需要自定义自己的 Group,可以通过以下配置来实现
spring.cloud.nacos.config.group=DEVELOP_GROUP
注意:该配置必须放在 botstrap 配置文件中,并且在添加配置时,Group 的值一定要和spring.cloud.nacos.config.group
的配置值一致
3.6、自定义拓展的 DataId 配置
3.6.1、shared-configs
Spring Cloud Alibaba Nacos Config从0.2.1版本后,可支持自定义Data ld的配置。一个完整的配置案例如下所示:
新建如下配置
该配置只有三个属性
添加如下配置
spring:
cloud:
nacos:
config:
shared-configs:
- dataId: com.hudu.mall.common.properties
refresh: true
# group: 默认是 DEFAULT_GROUP
可以看到成功获取到配置,并且优先级是小于 profile配置 和 默认配置文件,
如果有多个配置,会以后获取到的配置为准。
spring:
cloud:
nacos:
config:
shared-configs:
- dataId: com.hudu.mall.common.properties
refresh: true
# group: 默认是 DEFAULT_GROUP
- dataId: com.hudu.mall.common02.properties
refresh: true
# group: 默认是 DEFAULT_GROUP
结果如下
3.6.2、extension-configs
创建如下配置
配置文件内容如下
spring:
cloud:
nacos:
config:
shared-configs:
- dataId: com.hudu.mall.common.properties #[0]
refresh: true
# group: 默认是 DEFAULT_GROUP
- dataId: com.hudu.mall.common02.properties #[1]
refresh: true
# group: 默认是 DEFAULT_GROUP
extension-configs[0]:
dataId: com.hudu.mall.common03.properties
refresh: true
结果如下
四、@RefreshScope
@Value
注解可以获取到配置中心的值,但是无动态感知修改后的值,需要利用@RefreshScope
注解
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${user.name}")
public String username;
@RequestMapping("show")
public String show() {
return username;
}
}
五、总结
配置文件优先级如下
profile > 默认配置文件 > extension-configs(下标越大优先级越大) > shared-configs(下标越大优先级越大)
本作品采用《CC 协议》,转载必须注明作者和本文链接