【Nacos】配置中心
1. 基础
1.1概念
在系统开发过程中,开发者通常会将一些需要变更的参数、变量等从代码中分离出来独立管理,以独立的配置文件的形式存在。目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进行适配。配置管理一般包含在系统部署的过程中,由系统管理员或者运维人员完成。配置变更是调整系统运行时的行为的有效手段。
采用Nacos进行系统配置的编辑、存储、分发、变更管理、历史版本管理、变更审计等所有与配置相关的活动
Nacos官方API
1.2 nacos配置管理的模型
nacos配置管理, 通过namespace, group, dataId能够定位到一个配置集。模型的最佳实践
image.png
- Namespace: 代表不同的环境, 如: 开发、测试, 生产等
- Group: 可以代表某个项目, 如XX医疗项目, XX电商项目
- DataId: 每个项目下往往有若干个工程, 每个配置集(DataId)是一个工程的主配置文件
1.2.1 Nacos Server 中发布配置dataId命名规范
在 Nacos Spring Cloud 中,dataId 的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
- prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
- spring.profiles.active 即为当前环境对应的 profile,比如:dev
- file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
比如获取应用名称为example的应用在dev环境下的properties配置,dataid为example-dev.properties,在bootstrap.properties中配置如下
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=example
spring.profiles.active=dev
spring.cloud.nacos.config.file-extension=properties
1.2.2 Nacos Server 配置命名空间
根据环境进行命名空间分类,比如测试、预上线、正式环境等
image.png
image.png
2. Nacos Spring项目配置
首先在Nacos Server 中发布配置dataId 为example,内容为useLocalCache=true的text
image.png
2.1添加依赖 nacos-spring-context
<artifactId>nacos-spring-config-example</artifactId>
<packaging>war</packaging>
<name>nacos-spring-config-example</name>
<url>http://nacos.io</url>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-spring-context</artifactId>
</dependency>
</dependencies>
2.2启用 Nacos Spring 的配置管理服务
定义一个配置类,添加 @EnableNacosConfig 注解启用配置管理服务
@Configuration
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfiguration {
}
@NacosPropertySource 加载了 dataId 为 example 的配置源,并开启自动更新。
2.3通过 Nacos 的 @NacosValue 注解设置属性值。
@NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
private boolean useLocalCache;
//http://localhost:8080/config/get访问
@RequestMapping(value = "/get", method = GET)
@ResponseBody
public boolean get() {
return useLocalCache;
}
3. Spring Boot项目配置
本次演示读取yml文件配置属性,新建dataId,如果要读取yml文件,dataId名字必须含有.yml后缀,如sprinboot-example.yml,否则无法读取。
image.png
3.1 添加依赖
springboot的版本是1.x就引入0.1.x,springboot版本是2.x就引入0.2.x版本。这里使用的版本是0.2.7。官方例子使用的0.2.1,读取不到配置中心配置的yaml文件。
<nacos-config-spring-boot.version>0.2.7</nacos-config-spring-boot.version>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>nacos-config-spring-boot-starter</artifactId>
<version>${latest.version}</version>
</dependency>
3.2 application.properties 中配置 Nacos server 的地址
nacos.config.server-addr=127.0.0.1:8848
或
server:
port: 8081
nacos:
config:
server-addr: 127.0.0.1:8848
namespace: 5c3638e7-ca2c-46af-b47b-67b009c14fa1
3.3 在启动应用Application加载配置源
使用@NacosPropertySource 加载 dataId 为 example 的配置源,并开启自动更新。@NacosPropertySource配置需要引入的外部配置的namespace、groupId、dataId等信息。
@SpringBootApplication
@NacosPropertySource(dataId = "sprinboot-example.yml", autoRefreshed = true)
public class NacosConfigApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApplication.class, args);
}
}
3.4 通过 Nacos 的 @NacosValue 注解获取属性值。
使用${}表达式,冒号后可以填写默认值,当配置项不存在或者获取失败后,使用该默认值赋值。
@Controller
@RequestMapping("config")
public class ConfigController {
@NacosValue(value = "${server.tomcat.uri-encoding:''}", autoRefreshed = true)
private String tomcatEncode;
@RequestMapping(value = "/get", method = GET)
@ResponseBody
public String getTomcatEncode() {
return tomcatEncode;
}
}
3.5 通过 ConfigurableEnvironment 获取属性值
public static String getConfigByName(String key){
ApplicationContext applicationContext = SpringContextUtil.getApplicationContext();
ConfigurableEnvironment configurableEnvironment= (ConfigurableEnvironment) applicationContext.getEnvironment();
return configurableEnvironment.getProperty(key);
}
public static Boolean isRealEnvironment(){
String is_real = getConfigByName("is_real");
return !Strings.isNullOrEmpty(is_real) && "Y".equals(is_real.trim());
}
4. Spring Cloud项目配置
4.1 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
4.2 在 bootstrap.properties 中配置 Nacos server 的地址和应用名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=example
之所以需要配置 spring.application.name ,是因为它是构成 Nacos 配置管理 dataId字段的一部
4.3 通过 Spring Cloud 原生注解 @RefreshScope 实现配置自动更新
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${useLocalCache:false}")
private boolean useLocalCache;
@RequestMapping("/get")
public boolean get() {
return useLocalCache;
}
}
5.实际项目配置
5.1 引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
5.2 在项目中创建bootstrap.yml文件
spring:
application:
name: naocs-service
profiles:
active: dev
cloud:
nacos:
config:
# 配置文件的环境
group: ${spring.profiles.active}
# 配置文件的格式
file-extension: yaml
# 配置中心的地址
server-addr: 47.105.198.54:8848
# 配置文件prefix
prefix: ${spring.application.name}
#命名空间
namespace: mall
5.3 登录nacos,在nacos页面选择配置管理,创建配置文件
这里主要配置三个东西,Data ID、Group 以及要配置的内容。Data Id:naocs-service-dev.yaml
Group :dev
image.png
新建命名空间
image.png
6. 开发环境使用配置文件的问题
开发人员在本地开发调试,每个人的本地环境也许不一样,但是由于大家都是使用Nocas的同一个test配置。因此有些参数需要使用本地的配置,
bootstrap.yaml配置情况如下:
# 本地启动打开此处注解
base_server: http://192.168.18.61:8080
static_server: http://192.168.18.61:8080
logging:
level:
com.alibaba.nacos.client.config.impl: WARN
nacos:
username: test
password: 123456
addr: 192.150.10.222:8050
spring:
application:
name: wap
profiles:
active: test
cloud:
nacos:
server-addr: ${nacos.addr}
config:
username: ${nacos.username}
password: ${nacos.password}
file-extension: yaml
prefix: ${spring.application.name}
namespace: ${spring.profiles.active}
ext-config[0]:
data-id: redis-${spring.profiles.active}.yaml
Nacos配置:
server:
tomcat:
uri-encoding: UTF-8
max-threads: 1000
min-spare-threads: 30
# port: 80
servlet:
session:
timeout: PT30M
logging:
config: classpath:log4j2-wap.xml
spring:
cloud:
config: # 测试环境nacos不覆盖本地配置
# allow-override: false # 允许nacos被本地文件覆盖
override-none: true # nacos不覆盖任何本地文件
override-system-properties: false # nacos 覆盖系统属性。注意本地配置文件不是系统属性
(1)在Nacos配置
如果走Spring Cloud Config这一套,如果你想本地提供一些参数覆盖远程配置文件的属性,在没有远程配置文件的允许下,是无法覆盖的。Nacos中配置不覆盖本地文件
spring:
cloud:
config: # 测试环境nacos不覆盖本地配置
# allow-override: false # 允许nacos被本地文件覆盖
override-none: true # nacos不覆盖任何本地文件
override-system-properties: false # nacos 覆盖系统属性。注意本地配置文件不是系统属性
属性说明:
- overrideSystemProperties:是覆盖Java运行时参数的也就是说通过下面的方式提供的属性,是会被远程的配置文件给覆盖的(如果Nacos配置了server.port这个值的话,那么你不会得到期望的6666)
java -jar -Dserver.port=6666 myapp.jar
如果overrideSystemProperties设置为false,就可以得到期望的6666
- override-none
Nacos中设置为ture,Nacos中配置的任何属性不会覆盖任何已经存在的值。已存在的值是指非系统环境变量(如果你将overrideSystemProperties设置为false除外)。但如果 如此一来,我们通过命令行指定的参数 --xxxxx.xxxx=value,就不会被覆盖掉了。
总结:一般来说,我们只需要将overrideNone设置为true,就能够通过命令行的方式,即--xxxx.xxx=value的方式设置属性值了,而且不会被覆盖掉。
(2)在bootstrap.yaml配置
在bootstrap.yaml中配置本地参数,例如:
# 本地启动打开此处注解
base_server: http://192.168.18.61:8080
static_server: http://192.168.18.61:8080
不能在application.yaml中配置,因为Nacos配置优先级高
7 扩展DataId, 多配置处理
在实际开发中,我们不可能将所有的配置同时放在同一个配置文件中,那样会显得多而有杂。可以通过加载多个配置文件
7.1方法一
如果有多个配置文件, 我们可以使用扩展配置的方式, 添加多个配置文件
扩展配置id, 第一个扩展的配置id
#只有一个data-id. 没有group, 采用默认的DEFAULT_GROUP.
ext-config[0]:
data-id: ext-config-common01.yml
#定义了一个GLOBAL_GROUP. 全局配置
ext-config[1]:
data-id: ext-config-common02.yml
group: GLOBAL_GROUP
#定义为一个自动刷新的GROUP, 并设置自动刷新属性为true
ext-config[2]:
data-id: ext-config-common03.yml
group: REFRESH_GROUP
refresh: true #配置修改, 是否刷新
7.2 方法二
datasource-dev.yaml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#MySQL配置
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://47.105.198.54:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: xxxx
mybatis-plus-dev.yaml
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
在应用程序的bootstrap.yml里的config节点下增加配置:
spring:
profiles:
active: ${DEPLOY_ENV}
application:
name: product
cloud:
nacos:
config:
group: ${spring.profiles.active}
file-extension: yaml
server-addr: ${NACOS}
prefix: ${spring.application.name}
namespace: ${nacos.client.namespace}
extension-configs:
- dataId: datasource-${spring.profiles.active}.yaml
group: ${spring.profiles.active}
#是否刷新
refresh: true
- dataId: mybatis-plus-${spring.profiles.active}.yaml
group: ${spring.profiles.active}
refresh: true