首先在nacos发布配置,我们规划了两个服务service1、service2,并且想对这两个服务的配置进行集中维护。
浏览器访问 http://127.0.0.1:8848/nacos ,打开nacos控制台,并点击菜单配置管理->配置列表:
在Nacos添加如下的配置:
service1
Namespace: c67e4a97‐a698‐4d6d‐9bb1‐cfac5f5b51c4 #开发环境
Data ID: service1.yaml
Group : TEST_GROUP
配置格式: YAML
配置内容: common:
name: service1 config
Namespace: c67e4a97‐a698‐4d6d‐9bb1‐cfac5f5b51c4 #开发环境
Data ID: service2.yaml
Group : TEST_GROUP
配置格式: YAML
配置内容: common:
name: service2 config
为了规范依赖的版本,这里创建父工程,指定依赖的版本。
父工程pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo.nacos</groupId>
<artifactId>nacos-config</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>service1</module>
<module>service2</module>
</modules>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF‐8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF‐8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
本小节,我们将演示如何使用 Spring Cloud Alibaba Nacos Config在Spring Cloud应用中集成Nacos,通过Spring cloud原生方式快捷的获取配置内容。
Spring Cloud是什么:
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot
的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,集成最多的组件要属Netflix公司,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
Spring Cloud Alibaba Nacos Config是什么:
Spring Cloud Alibaba Nacos Discovery是Spring Cloud Alibaba的子项目,而Spring Cloud Alibaba是阿里巴巴公司提供的开源的基于Spring cloud的微服务套件合集,它致力于提供微服务开发的一站式解决方
案,可以理解为spring cloud是一套微服务开发的 标准 ,spring cloud alibaba与spring cloud Netflix是实现。使用 Spring Cloud Alibaba方案,开发者只需要添加一些注解和少量配置,就可以将 Spring Cloud 应用接入阿里分布式应用解决方案,通过阿里中间件来迅速搭建分布式应用系统。
由于Nacos是阿里的中间件,因此,若开发Spring cloud微服务应用,使用Spring Cloud Alibaba Nacos Config来集成Nacos的配置管理功能是比较明智的选择。
(1)新建项目service1
首先新增一个名为service1工程,并添加group ID 为 com.alibaba.cloud 和 artifact ID 为 spring-cloudstarter-alibaba-nacos-config 的 starter。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>nacos-config</artifactId>
<groupId>com.demo.nacos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service1</artifactId>
<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>
</project>
(2)bootstrap.yml配置
一般来说,spring boot的配置将在application.yml(也可以是application.properties)文件中编写, 由于使用外部配置中心,必须将原先的application.yml重命名为bootstrap.yml,bootstrap.yml如下所示:
spring.cloud.nacos.config.server-addr 指定了Nacos Server的网络地址和端口号。
server:
port: 56010 #启动端口 命令行注入
spring:
application:
name: service1 #项目名称
cloud:
nacos:
config:
server‐addr: 127.0.0.1:8848 # 配置中心地址
file‐extension: yml #dataid 的名字就是application的name加file-extension service1.yml
namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # 开发环境 指定具体的namespace
group: TEST_GROUP # 测试组
以上配置文件说明该应用将从地址为127.0.0.1:8848配置中心获取配置,通过以下信息定位配置集:
namespace:c67e4a97‐a698‐4d6d‐9bb1‐cfac5f5b51c4 # 开发环境
group:TEST_GROUP # 测试组
Data Id:service1.yaml
(3)启动配置客户端
新增Spring Boot 启动类,并增加获取配置的web访问端点/configs,通过标准的spring @Value 方式。
package com.demo.nacos.service1.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Description:
* DATE: 2022/1/26 10:23
*/
@RestController
@RefreshScope//实时刷新nacos配置中心的上下文
public class NacosController {
//通过value注解读取配置信息
@Value("${common.name}")
private String config1;
@GetMapping("/configs")
public String getConfigs(){
//读取配置信息
return config1;
}
}
service2的创建流程与service1一致:需要注意的是spring boot 启动端口要避免重复,spring.application.name为service2。
server:
port: 56020 #启动端口 命令行注入
spring:
application:
name: service2 #项目名称
cloud:
nacos:
config:
server‐addr: 127.0.0.1:8849,127.0.0.1:8850,127.0.0.1:8851 # 配置中心地址
file‐extension: yml #dataid 的名字就是application的name加file-extension service2.yml
namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # 开发环境 指定具体的namespace
group: TEST_GROUP # 测试组
# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
ext‐config[0]:
data‐id: ext-config-common01.properties
# 2、Data Id 不在默认的组,不支持动态刷新
ext‐config[1]:
data‐id: ext-config-common02.properties
group: GLOBALE_GROUP
# 3、Data Id 既不在默认的组,也支持动态刷新
ext‐config[2]:
data‐id: ext-config-common03.properties
group: REFRESH_GROUP
refresh: true
分别启动service1和service2项目,并分别访问 /configs进行测试,不同项目能够获取各自的配置内容。
基于上面快速上手的例子,若要实现配置的动态更新,只需要进行如下改造:
// 注入配置文件上下文
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping(value = "/configs")
public String getConfigs(){
return applicationContext.getEnvironment().getProperty("common.name");
}
Note 可以通过配置spring.cloud.nacos.config.refresh.enabled=false来关闭动态刷新
支持自定义 namespace的配
在没有明确指定 ${spring.cloud.nacos.config.namespace} 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespace。如果需要使用自定义的命名空间,可以通过以下配置来实现:
spring:
cloud:
nacos:
config:
namespace: b3404bc0‐d7dc‐4855‐b519‐570ed34b62d7
Note:该配置必须放在 bootstrap.yml文件中。此外spring.cloud.nacos.config.namespace 的值是 namespace
对应的 id,id 值可以在 Nacos 的控制台获取。并且在添加配置时注意不要选择其他的 namespae,否则将会导致读取不到正确的配置。
支持自定义 Group 的配置
在没有明确指定 ${spring.cloud.nacos.config.group} 配置的情况下, 默认使用的是 DEFAULT_GROUP 。如果需要自定义自己的 Group,可以通过以下配置来实现:
spring:
cloud:
nacos:
config:
group: DEVELOP_GROUP
Note:该配置必须放在 bootstrap.properties 文件中。并且在添加配置时 Group 的值一定要和spring.cloud.nacos.config.group 的配置值一致。
Spring Cloud Alibaba Nacos Config可支持自定义 Data Id 的配置。 一个完整的配置案例如下所示:
下边我们在service2微服务下配置扩展。
server:
port: 56020 #启动端口 命令行注入
spring:
application:
name: service2 #项目名称
cloud:
nacos:
config:
server‐addr: 127.0.0.1:8849,127.0.0.1:8850,127.0.0.1:8851 # 配置中心地址
file‐extension: yml #dataid 的名字就是application的name加file-extension service2.yml
namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # 开发环境 指定具体的namespace
group: TEST_GROUP # 测试组
# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
ext‐config[0]:
data‐id: ext‐config‐common01.properties
# 2、Data Id 不在默认的组,不支持动态刷新
ext‐config[1]:
data‐id: ext‐config‐common02.properties
group: GLOBALE_GROUP
# 3、Data Id 既不在默认的组,也支持动态刷新
ext‐config[2]:
data‐id: ext‐config‐common03.properties
group: REFRESH_GROUP
refresh: true
可以看到:
Note : spring.cloud.nacos.config.ext-config[n].data-id 的值必须带文件扩展名,文件扩展名既可支持properties,又可以支持 yaml/yml。 此时 spring.cloud.nacos.config.file-extension 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
通过自定义扩展的 Data Id 配置,既可以解决多个应用间配置共享的问题,又可以支持一个应用有多个配置文件。
测试: 配置ext-config-common01.properties:
配置ext-config-common02.properties
配置ext-config-common03.properties
编写测试代码:
package com.demo.nacos.service2.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.xml.ws.Action;
/**
* Description:
* DATE: 2022/1/26 10:32
*/
@RestController
public class NacosController {
// @Value("${common.name}")
// private String configs;
@Autowired
ConfigurableApplicationContext applicationContext;
@GetMapping("/configs")
public String getConfigs(){
return applicationContext.getEnvironment().getProperty("common.name");
}
@GetMapping("/configs2")
public String getConfigs2(){
String name1 = applicationContext.getEnvironment().getProperty("common.name1");
String birthday = applicationContext.getEnvironment().getProperty("common.birthday");
String age = applicationContext.getEnvironment().getProperty("common.age");
return "name1="+name1+"birthday="+birthday+"age="+age;
}
}
重启应用,访问http://localhost:56011/configs2,观察配置是否成功获取。
输出:
service2 config+12+beijing+1990‐1‐1+zhangsansanff
为了更加清晰的在多个应用间配置共享的 Data Id ,你可以通过以下的方式来配置:
spring:
cloud:
nacos:
config:
shared‐dataids: ext‐config‐common01.properties,ext‐config‐common02.properties
refreshable‐dataids: ext‐config‐common01.properties
可以看到:
Note:通过 spring.cloud.nacos.config.shared-dataids 来支持多个共享配置的 Data Id 时, 多个共享配
置间的一个优先级的关系我们约定:按照配置出现的先后顺序,即后面的优先级要高于前面。
Note:通过 spring.cloud.nacos.config.shared-dataids 来配置时,Data Id 必须带文件扩展名,文件扩
展名既可支持 properties,也可以支持 yaml/yml。 此时 spring.cloud.nacos.config.file-extension 的
配置对自定义扩展配置的 Data Id 文件扩展名没有影响。
Note: spring.cloud.nacos.config.refreshable-dataids 给出哪些需要支持动态刷新时,Data Id 的值也
必须明确给出文件扩展名。
测试输出:
service2 config+12+beijing+null+null
为什么后边两个值为null?
共享DataId的配置使用默认的group即DEFAULT_GROUP,ext-config-common02.properties不属于DEFAULT_GROUP。
共享DataId的配置相比扩展的 Data Id 配置,它把group固定为DEFAULT_GROUP,建议使用扩展的 Data Id 配置,因为扩展的 Data Id 配置也可以实现共享DataId配置。
Spring Cloud Alibaba Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置。
当三种方式共同使用时,他们的一个优先级关系是:C > B >A
测试,屏蔽共享dataId,放开ext-config,如下:
server:
port: 56020 #启动端口 命令行注入
spring:
application:
name: service2 #项目名称
cloud:
nacos:
config:
server‐addr: 127.0.0.1:8849 # 配置中心地址
file‐extension: yml #dataid 的名字就是application的name加file-extension service2.yml
namespace: 20dd9cd5-8ce6-4f73-8380-dfa3074ce5a8 # 开发环境 指定具体的namespace
group: TEST_GROUP # 测试组
# config external configuration
# 1、Data Id 在默认的组 DEFAULT_GROUP,不支持配置的动态刷新
ext‐config[0]:
data‐id: ext‐config‐common01.properties
# 2、Data Id 不在默认的组,不支持动态刷新
ext‐config[1]:
data‐id: ext‐config‐common02.properties
group: GLOBALE_GROUP
# 3、Data Id 既不在默认的组,也支持动态刷新
ext‐config[2]:
data‐id: ext‐config‐common03.properties
group: REFRESH_GROUP
refresh: true
修改ext-config-common03.properties:
service2 config aaa+15+beijing+1990‐1‐1+zhangsansanff
修改:service1.yaml
service2 config aaa+25+beijing+1990‐1‐1+zhangsansanff
通过测试发现:B和C同时存在,C优先级高。
通过设置 spring.cloud.nacos.config.enabled = false 来完全关闭 Spring Cloud Nacos Config