1. 基礎(chǔ)
1.1概念
在系統(tǒng)開發(fā)過程中拾碌,開發(fā)者通常會(huì)將一些需要變更的參數(shù)曹铃、變量等從代碼中分離出來獨(dú)立管理绞佩,以獨(dú)立的配置文件的形式存在冬阳。目的是讓靜態(tài)的系統(tǒng)工件或者交付物(如 WAR颤霎,JAR 包等)更好地和實(shí)際的物理運(yùn)行環(huán)境進(jìn)行適配媳谁。配置管理一般包含在系統(tǒng)部署的過程中,由系統(tǒng)管理員或者運(yùn)維人員完成友酱。配置變更是調(diào)整系統(tǒng)運(yùn)行時(shí)的行為的有效手段晴音。
采用Nacos進(jìn)行系統(tǒng)配置的編輯、存儲(chǔ)缔杉、分發(fā)锤躁、變更管理、歷史版本管理或详、變更審計(jì)等所有與配置相關(guān)的活動(dòng)
Nacos官方API
1.2 nacos配置管理的模型
nacos配置管理, 通過namespace, group, dataId能夠定位到一個(gè)配置集系羞。模型的最佳實(shí)踐
- Namespace: 代表不同的環(huán)境, 如: 開發(fā)、測試霸琴, 生產(chǎn)等
- Group: 可以代表某個(gè)項(xiàng)目, 如XX醫(yī)療項(xiàng)目, XX電商項(xiàng)目
- DataId: 每個(gè)項(xiàng)目下往往有若干個(gè)工程, 每個(gè)配置集(DataId)是一個(gè)工程的主配置文件
1.2.1 Nacos Server 中發(fā)布配置dataId命名規(guī)范
在 Nacos Spring Cloud 中椒振,dataId 的完整格式如下:
${prefix}-${spring.profiles.active}.${file-extension}
- prefix 默認(rèn)為 spring.application.name 的值,也可以通過配置項(xiàng) spring.cloud.nacos.config.prefix來配置梧乘。
- spring.profiles.active 即為當(dāng)前環(huán)境對(duì)應(yīng)的 profile澎迎,比如:dev
- file-exetension 為配置內(nèi)容的數(shù)據(jù)格式,可以通過配置項(xiàng) spring.cloud.nacos.config.file-extension 來配置。目前只支持 properties 和 yaml 類型夹供。
比如獲取應(yīng)用名稱為example的應(yīng)用在dev環(huán)境下的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 配置命名空間
根據(jù)環(huán)境進(jìn)行命名空間分類罩引,比如測試各吨、預(yù)上線、正式環(huán)境等
2. Nacos Spring項(xiàng)目配置
首先在Nacos Server 中發(fā)布配置dataId 為example袁铐,內(nèi)容為useLocalCache=true的text
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 的配置管理服務(wù)
定義一個(gè)配置類揭蜒,添加 @EnableNacosConfig 注解啟用配置管理服務(wù)
@Configuration
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfiguration {
}
@NacosPropertySource 加載了 dataId 為 example 的配置源,并開啟自動(dòng)更新剔桨。
2.3通過 Nacos 的 @NacosValue 注解設(shè)置屬性值屉更。
@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項(xiàng)目配置
本次演示讀取yml文件配置屬性,新建dataId洒缀,如果要讀取yml文件瑰谜,dataId名字必須含有.yml后綴,如sprinboot-example.yml树绩,否則無法讀取萨脑。
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 在啟動(dòng)應(yīng)用Application加載配置源
使用@NacosPropertySource 加載 dataId 為 example 的配置源鹊杖,并開啟自動(dòng)更新。@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 注解獲取屬性值川尖。
使用${}表達(dá)式登下,冒號(hào)后可以填寫默認(rèn)值,當(dāng)配置項(xiàng)不存在或者獲取失敗后空厌,使用該默認(rèn)值賦值庐船。
@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項(xiàng)目配置
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 的地址和應(yīng)用名
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
spring.application.name=example
之所以需要配置 spring.application.name ,是因?yàn)樗菢?gòu)成 Nacos 配置管理 dataId字段的一部
4.3 通過 Spring Cloud 原生注解 @RefreshScope 實(shí)現(xiàn)配置自動(dòng)更新
@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {
@Value("${useLocalCache:false}")
private boolean useLocalCache;
@RequestMapping("/get")
public boolean get() {
return useLocalCache;
}
}
5.實(shí)際項(xiàng)目配置
5.1 引入依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
5.2 在項(xiàng)目中創(chuàng)建bootstrap.yml文件
spring:
application:
name: naocs-service
profiles:
active: dev
cloud:
nacos:
config:
# 配置文件的環(huán)境
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頁面選擇配置管理嘲更,創(chuàng)建配置文件
這里主要配置三個(gè)東西筐钟,Data ID、Group 以及要配置的內(nèi)容赋朦。Data Id:naocs-service-dev.yaml
Group :dev
新建命名空間
6. 開發(fā)環(huán)境使用配置文件的問題
開發(fā)人員在本地開發(fā)調(diào)試篓冲,每個(gè)人的本地環(huán)境也許不一樣李破,但是由于大家都是使用Nocas的同一個(gè)test配置。因此有些參數(shù)需要使用本地的配置壹将,
bootstrap.yaml配置情況如下:
# 本地啟動(dòng)打開此處注解
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: # 測試環(huán)境nacos不覆蓋本地配置
# allow-override: false # 允許nacos被本地文件覆蓋
override-none: true # nacos不覆蓋任何本地文件
override-system-properties: false # nacos 覆蓋系統(tǒng)屬性嗤攻。注意本地配置文件不是系統(tǒng)屬性
(1)在Nacos配置
如果走Spring Cloud Config這一套,如果你想本地提供一些參數(shù)覆蓋遠(yuǎn)程配置文件的屬性诽俯,在沒有遠(yuǎn)程配置文件的允許下妇菱,是無法覆蓋的。Nacos中配置不覆蓋本地文件
spring:
cloud:
config: # 測試環(huán)境nacos不覆蓋本地配置
# allow-override: false # 允許nacos被本地文件覆蓋
override-none: true # nacos不覆蓋任何本地文件
override-system-properties: false # nacos 覆蓋系統(tǒng)屬性暴区。注意本地配置文件不是系統(tǒng)屬性
屬性說明:
- overrideSystemProperties:是覆蓋Java運(yùn)行時(shí)參數(shù)的也就是說通過下面的方式提供的屬性闯团,是會(huì)被遠(yuǎn)程的配置文件給覆蓋的(如果Nacos配置了server.port這個(gè)值的話,那么你不會(huì)得到期望的6666)
java -jar -Dserver.port=6666 myapp.jar
如果overrideSystemProperties設(shè)置為false仙粱,就可以得到期望的6666
- override-none
Nacos中設(shè)置為ture房交,Nacos中配置的任何屬性不會(huì)覆蓋任何已經(jīng)存在的值。已存在的值是指非系統(tǒng)環(huán)境變量(如果你將overrideSystemProperties設(shè)置為false除外)伐割。但如果 如此一來候味,我們通過命令行指定的參數(shù) --xxxxx.xxxx=value,就不會(huì)被覆蓋掉了隔心。
總結(jié):一般來說白群,我們只需要將overrideNone設(shè)置為true,就能夠通過命令行的方式硬霍,即--xxxx.xxx=value的方式設(shè)置屬性值了川抡,而且不會(huì)被覆蓋掉。
(2)在bootstrap.yaml配置
在bootstrap.yaml中配置本地參數(shù)须尚,例如:
# 本地啟動(dòng)打開此處注解
base_server: http://192.168.18.61:8080
static_server: http://192.168.18.61:8080
不能在application.yaml中配置,因?yàn)镹acos配置優(yōu)先級(jí)高
7 擴(kuò)展DataId, 多配置處理
在實(shí)際開發(fā)中侍咱,我們不可能將所有的配置同時(shí)放在同一個(gè)配置文件中耐床,那樣會(huì)顯得多而有雜⌒ǜ可以通過加載多個(gè)配置文件
7.1方法一
如果有多個(gè)配置文件, 我們可以使用擴(kuò)展配置的方式, 添加多個(gè)配置文件
擴(kuò)展配置id, 第一個(gè)擴(kuò)展的配置id
#只有一個(gè)data-id. 沒有g(shù)roup, 采用默認(rèn)的DEFAULT_GROUP.
ext-config[0]:
data-id: ext-config-common01.yml
#定義了一個(gè)GLOBAL_GROUP. 全局配置
ext-config[1]:
data-id: ext-config-common02.yml
group: GLOBAL_GROUP
#定義為一個(gè)自動(dòng)刷新的GROUP, 并設(shè)置自動(dòng)刷新屬性為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
在應(yīng)用程序的bootstrap.yml里的config節(jié)點(diǎn)下增加配置:
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