4. Spring Cloud Alibaba Nacos Config
Nacos 是一个非常易用的动态服务发现、配置和服务治理平台,用于构建云原生应用。
使用Spring Cloud Alibaba Nacos Config快速访问基于Spring Cloud编程模型的Nacos配置管理功能。
4.1. 如何引入Nacos Config来管理配置文件
引入以下Starter
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
4.2. 快速开始
Nacos Config 使用 DataId
和 GROUP
来定位一个配置。
下面这张图片展示了一个DataId
为 myDataid,GROUP
为 DEFAULT_GROUP, 使用Properties格式的配置。
图2. Nacos Config 示例
4.2.1. 初始化 Nacos Server
对于特定的启动方式,参考"Spring Cloud Alibaba Nacos 服务发现"的"启动 Nacos Server"部分。
Nacos 启动之后,添加配置:
Data ID: nacos-config.properties
Group : DEFAULT_GROUP
Configuration format: Properties
Configuration content: user.name=nacos-config-properties
user.age=90
注意:默认的配置格式是 Properties
客户端使用
如果您想使用 Nacos 来管理应用的外部配置文件,请添加以下依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
现在我们可以新建一个经典的 Spring Boot 应用程序
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
System.err.println("user name :" +userName+"; age: "+userAge);
}
}
运行这个示例之前,我们需要在bootstrap.properties中配置 Nacos 服务的地址,比如:
# DataId By default, the `spring.application.name` configuration is combined with the file extension (the configuration format uses properties by default), and the GROUP is not configured to use DEFAULT_GROUP by default. Therefore, the Nacos Config configuration corresponding to the configuration file has a DataId of nacos-config.properties and a GROUP of DEFAULT_GROUP
spring.application.name=nacos-config
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
注意:如果您使用域名访问 Nacos 服务,
spring.cloud.nacos.config.server-addr
的格式应为Domain name:port
。 比如,如果Nacos服务的域名为abc.com.nacos,监听的端口为 80,相应的配置为spring.cloud.nacos.config.server-addr=abc.com.nacos:80
, 80 端口不能省略。
运行这个程序,您能看到以下输出:
2018-11-02 14:24:51.638 INFO 32700 --- [main] c.a.demo.provider.NacosConfigApplication : Started NacosConfigApplication 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
4.3. 添加 YAML 格式的配置
Nacos Config 也支持 YAML 格式,您只要完成以下两个步骤。
- 在 bootstrap.properties中添加下面这行来声明DataId的格式为yaml,如下:
# bootstrap.properties
spring.cloud.nacos.config.file-extension=yaml
- 在 Nacos 控制面板中添加 yaml 格式的 DataId 配置,如下所示:
Data ID: nacos-config.yaml
Group : DEFAULT_GROUP
Configuration format: YAML
Configuration content: user.name: nacos-config-yaml
user.age: 68
完成上述两个步骤之后,重新启动测试程序,您能看到以下输出
2018-11-02 14:59:00.484 INFO 32928 --- [main] c.a.demo.provider.NacosConfigApplication:Started NacosConfigApplication 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
4.4. 支持动态更新配置
Nacos Config 同样支持动态更新配置,测试代码如下:
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
while(true) {
//When configurations are refreshed dynamically, they will be updated in the Enviroment, therefore here we retrieve configurations from Environment every other second.
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
//Read the updated value from Enviroment
user name :nacos-config-yaml-update; age: 68
user name :nacos-config-yaml-update; age: 68
4.5. 支持 Profile 级别的配置
当您使用 Nacos COnfig 加载配置文件时,DataId 为${spring.application.name}. ${file-extension:properties}
和${spring.application.name}-${profile}. ${file-extension:properties}
的基础配置文件均会被加载。如果您想在不同的环境中使用不同的配置,您可以使用 Spring 提供的 ${spring.profiles.active}
配置属性。
spring.profiles.active=develop
注意:当您要指定特定的配置文件时,bootstrap.properties 文件必须指定
${spring.profiles.active}
在 Nacos 中加入一个DataId为 nacos-config-develop.yaml 的基础配置,如下所示
Data ID: nacos-config-develop.yaml Group : DEFAULT_GROUP Configuration format: YAML Configuration content: current.env: develop-env
运行下面这个 Spring Boot 测试程序
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(NacosConfigApplication.class, args);
while(true) {
String userName = applicationContext.getEnvironment().getProperty("user.name");
String userAge = applicationContext.getEnvironment().getProperty("user.age");
//Get the current deployment environment
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
如果您要切换到生产(production)环境,需要修改${spring.profiles.active}
的值:
spring.profiles.active=product
同时,您需要在 Nacos 添加您生产环境的基础配置。例如,您可以为您的生产环境添加一个 DataId 为 nacos-config-product.yaml 的配置:
Data ID: nacos-config-product.yaml Group : DEFAULT_GROUP Configuration format: YAML Configuration content: 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
4.6 支持自定义命名空间(namespace)
关于 Nacos 命名空间的详细介绍,参考Nacos 概念。
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
如果没有为${spring.cloud.nacos.config.namespace}
指定特定的值,应用程序将使用名为"Public"的命名空间。当然您也可以通过以下方式自定义命名空间:
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
注意:这个配置属性必须写在 bootstrap.properties 文件中,
spring.cloud.nacos.config.namespace
的值是命名空间(namespace)的 ID 并且 Nacos 管理面板必须能检索到这个 namespace。不要在添加配置的过程中选取其他命名空间,否则无法正确读取配置。
4.7 支持自定义Group
当您没有特别指定{spring.cloud.nacos.config.group}
的值时,将使用 DEFAULT_GROUP 作为 Group 的默认值,可以使用以下方式自定义 Group:
spring.cloud.nacos.config.group=DEVELOP_GROUP
注意:这个配置属性必须写在 bootstrap.properties 文件中,而且Group的值必须与
spring.cloud.nacos.config.group.
保持一致。
4.8 支持自定义DataId
在 Spring Cloud Alibaba Nacos Config 中, DataId是可以自定义的。关于这个部分的详细设计,参考Github issue。以下代码是一个完整示例:
spring.application.name=opensource-service-provider
spring.cloud.nacos.config.server-addr=127.0.0.1:8848
# config external configuration
# 1. Data Id is in the default group of DEFAULT_GROUP, and dynamic refresh of configurations is not supported.
spring.cloud.nacos.config.ext-config[0].data-id=ext-config-common01.properties
# 2. Data Id is not in the default group, and dynamic refresh of configurations is not supported.
spring.cloud.nacos.config.ext-config[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.ext-config[1].group=GLOBALE_GROUP
# 3. Data Id is not in the default group and dynamic referesh of configurations is supported.
spring.cloud.nacos.config.ext-config[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.ext-config[2].group=REFRESH_GROUP
spring.cloud.nacos.config.ext-config[2].refresh=true
可以看到:
- 可以通过配置
spring.cloud.nacos.config.ext-config[n].data-id
来支持多个 DataId。 - 可以通过配置
spring.cloud.nacos.config.ext-config[n].group
来指定DataId的group,如果没有,将使用默认值DEFAULT_GROUP
。 - 可以通过配置
spring.cloud.nacos.config.ext-config[n].refresh
来决定是否支持DataId是否支持动态更新。默认为不支持。
注意:当使用多个DataId进行配置时,其优先级取决于
spring.cloud.nacos.config.ext-config[n].data-id
中的"n"。n 的值越大,优先级越高。
注意:
spring.cloud.nacos.config.ext-config[n].data-id
的值必须包含文件后缀,可以是.properties
或者.yaml/.yml
。spring.cloud.nacos.config.file-extension
的值对自定义DataId的文件后缀不生效。
自定义DataId的配置允许在多个应用程序中共享。同时,也支持一个应用程序使用多个配置。
以更清晰的方式在多个应用程序中共享一个DataId, 可以通过以下方式:
spring.cloud.nacos.config.shared-dataids=bootstrap-common.properties,all-common.properties
spring.cloud.nacos.config.refreshable-dataids=bootstrap-common.properties
可以看到:
- 可以通过配置
spring.cloud.nacos.config.shared-dataids
来共享多个DataId,使用逗号","隔开。 spring.cloud.nacos.config.refreshable-dataids
用来指定哪些 DataId 是可以动态更新的,当这些配置发生变化时,应用程序可以获取最新的配置,使用逗号","隔开。如果没有指定该属性,所有的DataId默认不支持动态更新。
注意:当您使用
spring.cloud.nacos.config.shared-dataids
来配置多个共享的DataId配置时,我们约定在共享的配置中使用以下优先级:DataId 配置的先后顺序决定了优先级。后面出现的DataId优先级高于前面的。
注意:
spring.cloud.nacos.config.ext-config[n].data-id
的值必须包含文件后缀,可以是.properties
或者.yaml/.yml
。spring.cloud.nacos.config.file-extension
的值对自定义DataId的文件后缀不生效。
注意:当您使用
spring.cloud.nacos.config.refreshable-dataids
指定支持动态更新的 DataId 时,指定的 DataId 也必须包含文件后缀。
4.9. Nacos Config Endpoint
Nacos Config 提供了一个 ID 为 nacos-config 的内部端点(Endpoint)。
该端点暴露一段包含三个属性的 Json:
- Sources: 应用程序当前的配置信息。
- RefreshHistory: 配置更新历史。
- NacosConfigProperties: 当前服务使用的Nacos基础配置
下面展示一个服务实例访问该端点的结果:
{
"NacosConfigProperties": {
"serverAddr": "127.0.0.1:8848",
"encode": null,
"group": "DEFAULT_GROUP",
"prefix": null,
"fileExtension": "properties",
"timeout": 3000,
"endpoint": null,
"namespace": null,
"accessKey": null,
"secretKey": null,
"contextPath": null,
"clusterName": null,
"name": null,
"sharedDataids": "base-common.properties,common.properties",
"refreshableDataids": "common.properties",
"extConfig": null
},
"RefreshHistory": [{
"timestamp": "2019-07-29 11:20:04",
"dataId": "nacos-config-example.properties",
"md5": "7d5d7f1051ff6571e2ec9f90887d9d91"
}],
"Sources": [{
"lastSynced": "2019-07-29 11:19:04",
"dataId": "common.properties"
}, {
"lastSynced": "2019-07-29 11:19:04",
"dataId": "base-common.properties"
}, {
"lastSynced": "2019-07-29 11:19:04",
"dataId": "nacos-config-example.properties"
}]
}
4.10. 禁用 Nacos Config 自动配置
使用spring.cloud.nacos.config.enabled = false
来禁用 Nacos Config 自动配置
4.11. 关于 Nacos Config Starter 的更多配置信息
Configuration | Key | Default Value | Description |
---|---|---|---|
Server address | spring.cloud.nacos.config.server-addr | IP and port of the Nacos Server listener | |
Dataid from nacos config | spring.cloud.nacos.config.name | First take the prefix, then go to the name, and finally take spring.application.name | |
Dataid from nacos config | spring.cloud.nacos.config.prefix | First take the prefix, then go to the name, and finally take spring.application.name | |
Encode for nacos config content | spring.cloud.nacos.config.encode | Encode for nacos config content | |
GROUP for nacos config | GROUP for nacos config | DEFAULT_GROUP | GROUP for nacos config |
The suffix of nacos config dataId, also the file extension of config content. | spring.cloud.nacos.config.fileExtension | properties | The suffix of nacos config dataId, also the file extension of config content(now support properties or yaml(yml)) |
Timeout for get config from nacos | spring.cloud.nacos.config.timeout | 3000 | Timeout for get config from nacos |
Endpoint | spring.cloud.nacos.config.endpoint | Endpoint | |
Namespace | spring.cloud.nacos.config.namespace | Namespace | |
AccessKey | spring.cloud.nacos.config.accessKey | Alibaba Cloud account accesskey | |
SecretKey | spring.cloud.nacos.config.secretKey | Alibaba Cloud account secretkey | |
The context path of Nacos Server | spring.cloud.nacos.config.contextPath | The context path of Nacos Server | |
Cluster name | spring.cloud.nacos.config.clusterName | Cluster name | |
Dataid for Shared Configuration | spring.cloud.nacos.config.sharedDataids | Dataid for Shared Configuration, split by “,” | |
Dynamic refresh dataid for Shared Configuration | spring.cloud.nacos.config.refreshableDataids | Dynamic refresh dataid for Shared Configuration, split by “,” | |
custom dataid | spring.cloud.nacos.config.extConfig | It’s a List,build up by Config POJO. Config has 3 attributes, dataId, group and refresh |