Nacos 提供用于存儲配置和其他中繼資料的 key/value 存儲,為分布式系統中的外部化配置提供伺服器端和用戶端支援。使用 Spring Cloud Alibaba Nacos Config,您可以在 Nacos Server 集中管理你 Spring Cloud 應用的外部屬性配置。
Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,用戶端和伺服器上的概念與 Spring Environment 和 PropertySource 有着一緻的抽象,在特殊的 bootstrap 階段,配置被加載到 Spring 環境中。當應用程式通過部署管道從開發到測試再到生産時,您可以管理這些環境之間的配置,并確定應用程式具有遷移時需要運作的所有内容。
快速開始
Nacos 服務端初始化
1、啟動Nacos Server。啟動方式可見 Nacos 官網
2、啟動好Nacos之後,在Nacos添加如下的配置:
Data ID: nacos-config.properties
Group : DEFAULT_GROUP
配置格式: Properties
配置内容: user.name=nacos-config-properties
user.age=90
Note | 注意dataid是以 properties(預設的檔案擴充名方式)為擴充名。 |
用戶端使用方式
如果要在您的項目中使用 Nacos 來實作應用的外部化配置,使用 group ID 為
com.alibaba.cloud
和 artifact ID 為
spring-cloud-starter-alibaba-nacos-config
的 starter。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
現在就可以建立一個标準的 Spring Boot 應用。
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :"+userName+"; age: "+userAge);
}
}
在運作此 Example 之前, 必須使用 bootstrap.properties 配置檔案來配置Nacos Server 位址,例如:
bootstrap.properties
spring.application.name=nacos-config
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
Note | 注意當你使用域名的方式來通路 Nacos 時, 配置的方式為 。 例如 Nacos 的域名為abc.com.nacos,監聽的端口為 80,則 。 注意 80 端口不能省略。 |
啟動這個 Example,可以看到如下輸出結果:
2018-11-02 14:24:51.638 INFO 32700 --- [main] c.a.demo.provider.ProviderApplication : Started ProviderApplication in 14.645 seconds (JVM running for 15.139)
user name :nacos-config-properties; age: 90
2018-11-02 14:24:51.688 INFO 32700 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@a8c5e74: startup date [Fri Nov 02 14:24:51 CST 2018]; root of context hierarchy
2018-11
基于 dataid 為 yaml 的檔案擴充名配置方式
spring-cloud-starter-alibaba-nacos-config 對于 yaml 格式也是完美支援的。這個時候隻需要完成以下兩步:
1、在應用的 bootstrap.properties 配置檔案中顯示的聲明 dataid 檔案擴充名。如下所示
bootstrap.properties
spring.cloud.nacos.config.file-extension=yaml
2、在 Nacos 的控制台新增一個dataid為yaml為擴充名的配置,如下所示:
Data ID: nacos-config.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容: user.name: nacos-config-yaml
user.age: 68
這兩步完成後,重新開機測試程式,可以看到如下輸出結果。
2018-11-02 14:59:00.484 INFO 32928 --- [main] c.a.demo.provider.ProviderApplication:Started ProviderApplication in 14.183 seconds (JVM running for 14.671)
user name :nacos-config-yaml; age: 68
2018-11-02 14:59:00.529 INFO 32928 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@265a478e: startup date [Fri Nov 02 14:59:00 CST 2018]; root of context hierarchy
支援配置的動态更新
spring-cloud-starter-alibaba-nacos-config 也支援配置的動态更新,啟動 Spring Boot 應用測試的代碼如下:
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.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);
}
}
}
如下所示,當變更user.name時,應用程式中能夠擷取到最新的值:
user name :nacos-config-yaml; age: 68
user name :nacos-config-yaml; age: 68
user name :nacos-config-yaml; age: 68
2018-11-02 15:04:25.069 INFO 32957 --- [-127.0.0.1:8848] o.s.boot.SpringApplication : Started application in 0.144 seconds (JVM running for 71.752)
2018-11-02 15:04:25.070 INFO 32957 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@10c89124: startup date [Fri Nov 02 15:04:25 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@6520af7
2018-11-02 15:04:25.071 INFO 32957 --- [-127.0.0.1:8848] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6520af7: startup date [Fri Nov 02 15:04:24 CST 2018]; root of context hierarchy
//從 Enviroment 中 讀取到更改後的值
user name :nacos-config-yaml-update; age: 68
user name :nacos-config-yaml-update; age: 68
Note | 你可以通過配置 來關閉動态重新整理 |
可支援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
Note | ${spring.profiles.active} 當通過配置檔案來指定時必須放在 bootstrap.properties 檔案中。 |
Nacos 上新增一個dataid為:nacos-config-develop.yaml的基礎配置,如下所示:
Data ID: nacos-config-develop.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容: current.env: develop-env
啟動 Spring Boot 應用測試的代碼如下:
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(ProviderApplication.class, args);
while(true) {
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
//擷取目前部署的環境
String currentEnv = applicationContext.getEnvironment().getProperty("current.env");
System.err.println("in "+currentEnv+" enviroment; "+"user name :" + userName + "; age: " + userAge);
TimeUnit.SECONDS.sleep(1);
}
}
}
啟動後,可見控制台的輸出結果:
in develop-env enviroment; user name :nacos-config-yaml-update; age: 68
2018-11-02 15:34:25.013 INFO 33014 --- [ Thread-11] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6f1c29b7: startup date [Fri Nov 02 15:33:57 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@63355449
如果需要切換到生産環境,隻需要更改
${spring.profiles.active}
參數配置即可。如下所示:
spring.profiles.active=product
同時生産環境上 Nacos 需要添加對應 dataid 的基礎配置。例如,在生成環境下的 Naocs 添加了dataid為:nacos-config-product.yaml的配置:
Data ID: nacos-config-product.yaml
Group : DEFAULT_GROUP
配置格式: YAML
配置内容: current.env: product-env
啟動測試程式,輸出結果如下:
in product-env enviroment; user name :nacos-config-yaml-update; age: 68
2018-11-02 15:42:14.628 INFO 33024 --- [Thread-11] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6aa8e115: startup date [Fri Nov 02 15:42:03 CST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@19bb07ed
Note | 此案例中我們通過 的方式寫死在配置檔案中,而在真正的項目實施過程中這個變量的值是需要不同環境而有不同的值。這個時候通常的做法是通過 參數指定其配置來達到環境間靈活的切換。 |
支援自定義 namespace 的配置
首先看一下 Nacos 的 Namespace 的概念, Nacos 概念
用于進行租戶粒度的配置隔離。不同的命名空間下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用場景之一是不同環境的配置的區分隔離,例如開發測試環境和生産環境的資源(如配置、服務)隔離等。
在沒有明确指定
${spring.cloud.nacos.config.namespace}
配置的情況下, 預設使用的是 Nacos 上 Public 這個namespae。如果需要使用自定義的命名空間,可以通過以下配置來實作:
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
支援自定義擴充的 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
可以看到:
- 通過
的配置方式來支援多個 Data Id 的配置。spring.cloud.nacos.config.extension-configs[n].data-id
- 通過
的配置方式自定義 Data Id 所在的組,不明确配置的話,預設是 DEFAULT_GROUP。spring.cloud.nacos.config.extension-configs[n].group
- 通過
的配置方式來控制該 Data Id 在配置變更時,是否支援應用中可動态重新整理, 感覺到最新的配置值。預設是不支援的。spring.cloud.nacos.config.extension-configs[n].refresh
Note | 多個 Data Id 同時配置時,他的優先級關系是 其中 n 的值越大,優先級越高。 |
Note | 的值必須帶檔案擴充名,檔案擴充名既可支援 properties,又可以支援 yaml/yml。 此時 的配置對自定義擴充配置的 Data Id 檔案擴充名沒有影響。 |
通過自定義擴充的 Data Id 配置,既可以解決多個應用間配置共享的問題,又可以支援一個應用有多個配置檔案。
為了更加清晰的在多個應用間配置共享的 Data Id ,你可以通過以下的方式來配置:
# 配置支援共享的 Data Id
spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml
# 配置 Data Id 所在分組,預設預設 DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].group=GROUP_APP1
# 配置Data Id 在配置變更時,是否動态重新整理,預設預設 false
spring.cloud.nacos.config.shared-configs[0].refresh=true
可以看到:
- 通過
來支援多個共享 Data Id 的配置。spring.cloud.nacos.config.shared-configs[n].data-id
- 通過
來配置自定義 Data Id 所在的組,不明确配置的話,預設是 DEFAULT_GROUP。spring.cloud.nacos.config.shared-configs[n].group
- 通過
來控制該Data Id在配置變更時,是否支援應用中動态重新整理,預設false。spring.cloud.nacos.config.shared-configs[n].refresh
配置的優先級
- A: 通過
支援多個共享 Data Id 的配置spring.cloud.nacos.config.shared-configs[n].data-id
- B: 通過
的方式支援多個擴充 Data Id 的配置spring.cloud.nacos.config.extension-configs[n].data-id
- C: 通過内部相關規則(應用名、應用名+ Profile )自動生成相關的 Data Id 配置