Alibaba微服務元件 - Nacos配置中心
1. 什麼是Nacos配置中心
官方文件: https://github.com/alibaba/springcloudalibaba/wiki/Nacosconfig
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幾條街,
2. 快速開始
準備配置,nacos server中新建com.xiexie.maill.order
最佳實踐:
Namespace:代表不同環境,如開發、測試、生產環境。
Group:代表某專案,如XX醫療專案、XX電商專案
DataId:每個專案下往往有若干個工程(微服務),每個配置集(DataId)是一個工程(微服務)的主配置檔案
3. 許可權配置
如果需要對安全性做處理,需要開啟許可權
啟動許可權:修改application.properties
4. 搭建nacos-config服務
通過 Nacos Server 和 spring-cloud-starter-alibaba-nacos-config 實現配置的動態變更
4.1 引入依賴
<dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
4.2 新增bootstrap.properties(或者新增bootstrap.yml)
bootstrap.yml檔案
spring:
application:
# 會自動根據服務名去拉取nacos中Data Id對應的配置檔案,如果dataid跟服務名不一致,就需要手動指定dataid
# 跟服務名相同的dataid配置檔案,就叫做預設的配置檔案
# 除了預設的配置檔案properties副檔名,其他的所有dataid都需要加上字尾副檔名
name: com.xiexie.maill.order
cloud:
nacos:
server-addr: 192.168.5.133:8848
# 當nacos開啟許可權配置的時候 需要加我們的使用者名稱和密碼
username: nacos
password: nacos
# 繫結我們的名稱空間(如果是public則不需要寫,防止頻繁出現ClientWorker日誌)
config:
namespace: 6325e312-7f95-48d7-8d06-810047ed3956
group: group-test
# 基於 dataid 為 yaml 的副檔名配置方式
# nacos客戶端拉取的配置副檔名預設為properties,
# 一旦修改成非properties檔案格式,必須通過file-extension進行設定指定
# 只針對預設的配置檔案和profile,其他自定義dataid進行擴充套件可以隨意
file-extension: yaml
# 客戶端關閉動態重新整理配置檔案
# refresh-enabled: false
# shared-configs 自定義dataid擴充套件
shared-configs:
- dataId: com.xiexie.shared.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# 陣列list下標越大優先順序越大(list後面的優先順序大)
- dataId: com.xiexie.extension02.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# extension-configs 自定義dataid擴充套件
extension-configs:
- dataId: com.xiexie.extension.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# 陣列list下標越大優先順序越大(list後面的優先順序大)
- dataId: com.xiexie.extension02.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# 配置檔案的優先順序(優先順序大的會覆蓋優先順序小的,並且會形成互補) 下面的優先順序由大到小
# profile > 預設配置檔案 > extension-configs(組list下標越大優先順序越大(list後面的優先順序大)) > shared-configs(組list下標越大優先順序越大(list後面的優先順序大))
# com.xiexie.maill.order-dev.ymal(精緻匹配);
# com.xiexie.maill.order.ymal(同工程不同環境的通用配置);
# extension-configs 不同工程擴充套件配置(組list下標越大優先順序越大(list後面的優先順序大));
# shared-configs 不同工程通用配置(組list下標越大優先順序越大(list後面的優先順序大));
# ext-config(不同工程的); (廢棄方法 但是可以用)
# shared-dataids 不同工程通用配置; (廢棄方法 但是可以用)
如果是要指定profile的話在application.yml中設定,也可以在bootstrap.yml檔案中設定,這樣更好區分
application.yml
server:
port: 8050
# 配置profile指定配置檔案
spring:
profiles:
active: dev
# 在配置中心可以使用profile進行設定
# 只有預設的配置檔案才能結合使用profile進行使用
# 對應的dataid: ${spring.application.name}-${profile}.${file-extension:properties}
# profile的字尾必須跟隨預設配置檔案的格式來
4.3 啟動服務,測試微服務是否使用配置中心的配置
package com.xiexie.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.concurrent.TimeUnit;
/**
* @Description
* @Date 2022-04-12 9:11
* @Author xie
*/
@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");
String config = applicationContext.getEnvironment().getProperty("user.config");
System.err.println("user name :"+userName+"; age: "+userAge + "; config: " + config);
// 一秒鐘拉取一次
TimeUnit.SECONDS.sleep(1);
}
// nacos客戶端每10ms 去註冊中心拉取一次,是根據註冊中心的MDS值去更新的(每次更改配置中會有歷史版本,新版本會生成新的MD5值)
// 當發現客戶端快取的MD5值不一樣時,就會卡去更新的配置檔案資訊
/**
* 當一直出現c.a.n.client.config.impl.ClientWorker : [fixed-192.168.5.133_8848-public] [polling-resp] config changed
* 這個資訊時候,有兩個原因
* 1. 繫結我們的名稱空間為public時候,不需要指定預設就是,註釋掉;或者指定其他的名稱空間
* 2. 我們依賴的nacos客戶端版本跟服務端的版本不一致(一般情況都是對應的,有問題根據具體情況查驗)
*/
}
}
5. Config相關配置
Nacos 資料模型 Key 由三元組唯一確定, Namespace預設是空串,公共名稱空間(public),分組預設是DEFAULT_GROUP
5.1 支援配置的動態更新
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");
String config = applicationContext.getEnvironment().getProperty("user.config");
System.err.println("user name :"+userName+"; age: "+userAge + "; config: " + config);
// 一秒鐘拉取一次
TimeUnit.SECONDS.sleep(1);
}
// nacos客戶端每10ms 去註冊中心拉取一次,是根據註冊中心的MDS值去更新的(每次更改配置中會有歷史版本,新版本會生成新的MD5值)
// 當發現客戶端快取的MD5值不一樣時,就會卡去更新的配置檔案資訊
/**
* 當一直出現c.a.n.client.config.impl.ClientWorker : [fixed-192.168.5.133_8848-public] [polling-resp] config changed
* 這個資訊時候,有兩個原因
* 1. 繫結我們的名稱空間為public時候,不需要指定預設就是,註釋掉;或者指定其他的名稱空間
* 2. 我們依賴的nacos客戶端版本跟服務端的版本不一致(一般情況都是對應的,有問題根據具體情況查驗)
*/
}
5.2 可支援profile粒度的配置
spring-cloud-starter-alibaba-nacos-config 在載入配置的時候,不僅僅載入了以 dataid 為 ${spring.application.name}.${file-extension:properties}
為字首的基礎配置,還載入了dataid為 ${spring.application.name}-${profile}.${file-extension:properties}
的基礎配置。在日常開發中如果遇到多套環境下的不同配置,可以通過Spring 提供的 ${spring.profiles.active}
這個配置項來配置。
spring.profiles.active=develop
如果需要切換到生產環境,只需要更改 ${spring.profiles.active} 引數配置即可。
spring.profiles.active=product
此案例中我們通過 spring.profiles.active=<profilename> 的方式寫死在配置檔案中,而在真正的專案實施過程中這個變數的值是需要不同環境而有不同的值。這個時候通常的做法是通過 -Dspring.profiles.active=<profile> 引數指定其配置來達到環境間靈活的切換。
5.3 支援自定義 namespace 的配置
用於進行租戶粒度的配置隔離。不同的名稱空間下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用場景之一是不同環境的配置的區分隔離,例如開發測試環境和生產環境的資源(如配置、服務)隔離等。
在沒有明確指定 ${spring.cloud.nacos.config.namespace}
配置的情況下, 預設使用的是 Nacos 上 Public 這個namespae。如果需要使用自定義的名稱空間,可以通過以下配置來實現:
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
該配置必須放在 bootstrap.properties 檔案中。此外 spring.cloud.nacos.config.namespace 的值是 namespace 對應的 id,id 值可以在 Nacos 的控制檯獲取。並且在新增配置時注意不要選擇其他的 namespae,否則將會導致讀取不到正確的配置。
5.4 支援自定義 Group 的配置
在沒有明確指定 ${spring.cloud.nacos.config.group}
配置的情況下, 預設使用的是 DEFAULT_GROUP 。如果需要自定義自己的 Group,可以通過以下配置來實現:
spring.cloud.nacos.config.group=DEVELOP_GROUP
該配置必須放在 bootstrap.properties 檔案中。並且在新增配置時 Group 的值一定要和 spring.cloud.nacos.config.group 的配置值一致。
5.5 支援自定義擴充套件的 Data Id 配置
Spring Cloud Alibaba Nacos Config 從 0.2.1 版本後,可支援自定義 Data Id 的配置。關於這部分詳細的設計可參考 這裡。 一個完整的配置案例如下所示:
spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1、Data Id 在預設的組 DEFAULT_GROUP,不支援配置的動態重新整理
spring.cloud.nacos.config.extension-configs[0].data-id=ext-config-common01.properties
# 2、Data Id 不在預設的組,不支援動態重新整理
spring.cloud.nacos.config.extension-configs[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.extension-configs[1].group=GLOBALE_GROUP
# 3、Data Id 既不在預設的組,也支援動態重新整理
spring.cloud.nacos.config.extension-configs[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.extension-configs[2].group=REFRESH_GROUP
spring.cloud.nacos.config.extension-configs[2].refresh=true
可以看到:
- 通過 spring.cloud.nacos.config.extension-configs[n].data-id 的配置方式來支援多個 Data Id 的配置。
- 通過 spring.cloud.nacos.config.extension-configs[n].group 的配置方式自定義 Data Id 所在的組,不明確配置的話,預設是 DEFAULT_GROUP。
- 通過 spring.cloud.nacos.config.extension-configs[n].refresh 的配置方式來控制該 Data Id 在配置變更時,是否支援應用中可動態重新整理, 感知到最新的配置值。預設是不支援的。
多個 Data Id 同時配置時,他的優先順序關係是 spring.cloud.nacos.config.extension-configs[n].data-id 其中 n 的值越大,優先順序越高
spring.cloud.nacos.config.extension-configs[n].data-id 的值必須帶副檔名,副檔名既可支援 properties,又可以支援 yaml/yml。 此時 spring.cloud.nacos.config.file-extension 的配置對自定義擴充套件配置的 Data Id 副檔名沒有影響。
參考配置檔案bootstrap.yml
spring:
application:
# 會自動根據服務名去拉取nacos中Data Id對應的配置檔案,如果dataid跟服務名不一致,就需要手動指定dataid
# 跟服務名相同的dataid配置檔案,就叫做預設的配置檔案
# 除了預設的配置檔案properties副檔名,其他的所有dataid都需要加上字尾副檔名
name: com.xiexie.maill.order
cloud:
nacos:
server-addr: 192.168.5.133:8848
# 當nacos開啟許可權配置的時候 需要加我們的使用者名稱和密碼
username: nacos
password: nacos
# 繫結我們的名稱空間(如果是public則不需要寫,防止頻繁出現ClientWorker日誌)
config:
namespace: 6325e312-7f95-48d7-8d06-810047ed3956
group: group-test
# 基於 dataid 為 yaml 的副檔名配置方式
# nacos客戶端拉取的配置副檔名預設為properties,
# 一旦修改成非properties檔案格式,必須通過file-extension進行設定指定
# 只針對預設的配置檔案和profile,其他自定義dataid進行擴充套件可以隨意
file-extension: yaml
# 客戶端關閉動態重新整理配置檔案
# refresh-enabled: false
# shared-configs 自定義dataid擴充套件
shared-configs:
- dataId: com.xiexie.shared.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# 陣列list下標越大優先順序越大(list後面的優先順序大)
- dataId: com.xiexie.extension02.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# extension-configs 自定義dataid擴充套件
extension-configs:
- dataId: com.xiexie.extension.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# 陣列list下標越大優先順序越大(list後面的優先順序大)
- dataId: com.xiexie.extension02.properties
group: DEFAULT_GROUP # 預設值可以不寫
refresh: true
# 配置檔案的優先順序(優先順序大的會覆蓋優先順序小的,並且會形成互補) 下面的優先順序由大到小
# profile > 預設配置檔案 > extension-configs(組list下標越大優先順序越大(list後面的優先順序大)) > shared-configs(組list下標越大優先順序越大(list後面的優先順序大))
# com.xiexie.maill.order-dev.ymal(精緻匹配);
# com.xiexie.maill.order.ymal(同工程不同環境的通用配置);
# extension-configs 不同工程擴充套件配置(組list下標越大優先順序越大(list後面的優先順序大));
# shared-configs 不同工程通用配置(組list下標越大優先順序越大(list後面的優先順序大));
# ext-config(不同工程的); (廢棄方法 但是可以用)
# shared-dataids 不同工程通用配置; (廢棄方法 但是可以用)
5.6 配置的優先順序
Spring Cloud Alibaba Nacos Config 目前提供了三種配置能力從 Nacos 拉取相關的配置。
- A: 通過 spring.cloud.nacos.config.shared-configs[n].data-id 支援多個共享 Data Id 的配置
- B: 通過 spring.cloud.nacos.config.extension-configs[n].data-id 的方式支援多個擴充套件 Data Id 的配置
- C: 通過內部相關規則(應用名、應用名+ Profile )自動生成相關的 Data Id 配置
當三種方式共同使用時,他們的一個優先順序關係是:A < B < C
profile > 預設配置檔案 > extension-configs(組list下標越大優先順序越大(list後面的優先順序大)) > shared-configs(組list下標越大優先順序越大(list後面的優先順序大))