一、Nacos配置中心
前面说了三、Spring Cloud Alibaba组件nacos,主要介绍的是服务发现。该篇主要介绍配置中心的功能。
官方地址:
https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config。
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 应用的外部属性配置。
提升特性:
- 维护性:建立统一的配置文件,更改配置文件时所有使用该配置的微服务都能变更。
- 时效性:配置变更,能够及时通知相关服务。
- 安全性:不同的环境注册不同的命名空间,角色可以赋予不同的命名空间访问权限。
二、配置中心界面和相关功能说明
1、最佳划分归类
- Namespace-命名空间:代表不同环境,如开发、测试、生产环境。根据环境分类
- Group:代表某项目,如XX医疗项目、XX电商项目。根据项目分类。
- Datald:每个项目下往往有干个工程(微服务),每个配置集(Datald)是一个工程(微服务)的主配置文件。
2、配置集 ID-Data ID
Nacos 中的某个配置集的 ID。配置集 ID 是组织划分配置的维度之一。Data ID通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。此命名规则非强制。
常用格式:服务名-环境.文件格式
比如:application-dev.yml
注意dataId是以 properties(默认的文件扩展名方式)为扩展名,可以不加后缀。如果修改为其他格式,后缀必须跟着变。
3、配置分组
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
4、克隆配置
可以克隆到其他命名空间和分组中。
5、历史版本回滚
如果配错了,可以直接回滚。
6、权限管理
启动权限需在Nacos配置文件(nacos/conf/application.properties)中修改nacos.core.auth.enabled为true,默认为false。
### If turn on auth system:
nacos.core.auth.enabled=true
三、结合项目和nacos界面配置
快速开始官网地址:
https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
1、项目中添加依赖
<!--nacos config 配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、项目中配置文件配置。
项目中必须使用 bootstrap.properties 配置文件来配置Nacos Server 地址。 也支持bootstrap.yml文件。
bootstrap.yml:
server:
port: 8815
#应用名称,nacos会将该名称当做服务名称
spring:
application:
#会自动根据服务名拉取dataId对应的配置文件
#如果dataId和服务名不一致,需要手动指定dataId
name: order-service
cloud:
nacos:
username: nacos
password: nacos
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
#命名空间,可以根据空间进行一个隔离
namespace: public
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
3、测试
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) throws Exception{
ConfigurableApplicationContext applicationContext = SpringApplication.run(OrderApplication.class, args);
while(true) {
//当动态配置刷新时,会更新到 Enviroment中,因此这里每隔一秒中从Enviroment中获取配置
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(1);
}
}
}
四、其他扩展配置
(1)spring.cloud.nacos.config.refresh.enabled=false 来关闭动态刷新。就会感知不到配置的变化。
(2)可支持profile粒度的配置。常用格式配置:服务名-环境.yml。
dataId命名为
s p r i n g . a p p l i c a t i o n . n a m e − {spring.application.name}- spring.application.name−{profile}.${file-extension:properties}
的基础配置。只有默认的配置文件才能这么写,即服务名和dataId一致。
例如:
spring.application.name: order-service
nacos配置则为:order-service-dev.yml
(3)共享配置文件,常用 shared-configs配置。
比如创建所有服务所共享的配置文件:application-dev.yml
# 共享配置
shared-configs:
#data ID
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
具体参考官网:
https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-config
配置的优先级:
自己的配置文件(服务名+ Profile )自动生成相关的 Data Id 配置)> extension-configs >shared-configs
五、最终常用的配置文件
nacos界面的配置文件application-dev.yml为共享配置,order-service-dev.yml为order-service服务的配置。
server:
port: 8815
#应用名称,nacos会将该名称当做服务名称
spring:
application:
#会自动根据服务名拉取dataId对应的配置文件
#如果dataId和服务名不一致,需要手动指定dataId(extension-configs或shared-configs指定)
name: order-service
profiles:
# 环境配置
active: dev
cloud:
nacos:
username: nacos
password: nacos
#配置中心
config:
server-addr: 127.0.0.1:8848
#命名空间,可以根据空间进行一个隔离
namespace: public
# 配置文件格式。nacos客户端默认properties格式的文件,
#如果界面修改为其他格式就不能读取,则必须进行file-extension配置
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
#服务注册
discovery:
server-addr: 127.0.0.1:8848
#设置为永久实例,实例挂了还会存在。默认true为临时实例
ephemeral: false
#默认为 DEFAULT_GROUP,更细的相同特征的服务分组管理
group: DEFAULT_GROUP
六、刷新nacos中注入的value值修改后动态读取
使用@Value注解读取配置文件信息时,如需动态读取需加@RefreshScope注解。
测试:
重启后,修改nacos中order-service-dev.yml的user.name值,然后请求接口测试。
接口:http://localhost:8815/config/show。
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${user.name}")
public String name;
@RequestMapping("/show")
public String show(){
return name;
}
}