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的配置管理功能进行管理
### 5.2.1 发布配置
首先在Nacos上发布配置:service1、service2,并通过Nacos对两个服务的配置进行集中维护。
PS:本文是在dev命名空间新建了两个配置文件
(1) 在Nacos上配置service1
![image-20210110103158640.png](https://upload-images.jianshu.io/upload_images/18155748-a0e57ea60a437acf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
```yaml
common:
name: service1 config
(2) 在Nacos上配置service2
common:
name: service2 config
(3) 配置后如下图
5.2.2 创建父工程
为规范依赖的版本,需创建父工程并指定依赖的版本。
(1) 新建Maven工程
(2) 修改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>net.zhi365</groupId>
<artifactId>nacosconfig</artifactId>
<version>1.0</version>
<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.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<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>
<!-- 这个问题太坑了,是boot-maven中间那个【-】的问题,重新输入就好用了 -->
<!--<artifactId>spring-boot‐maven-plugin</artifactId>-->
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
5.2.3 微服务配置
本小节将演示如何使用Spring Cloud Alibaba Nacos Config在Spring Cloud应用中集成Nacos,通过Spring Cloud原生方式,快捷的获取配置内容
(1) 新建service1与service2模块
(2) 在两个pom.xml中添加依赖
<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>
(3) 添加配置文件bootstrap.yml
通常Spring Boot的配置文件为application.yml或application.properties,但由于使用外部配置中心,须将原来的配置文件改名为bootstrap.yml。
service1的bootstrap.yml
server:
port: 5601 # 启动端口 命令行注入
spring:
application:
name: service1
cloud:
nacos:
config:
server‐addr: localhost:8848 # 配置中心地址
file‐extension: yaml
namespace: 470cd824-4b0a-4001-bcac-8491cf2987f8 # 开发环境
group: DEFAULT_GROUP # 默认组
service2的bootstrap.yml
server:
port: 5602 # 启动端口 命令行注入
spring:
application:
name: service2
cloud:
nacos:
config:
server‐addr: localhost:8848 # 配置中心地址
file‐extension: yaml
namespace: 470cd824-4b0a-4001-bcac-8491cf2987f8 # 开发环境
group: DEFAULT_GROUP # 默认组
需要说明一下的是Nacos中的Data Id对应配置文件中的{spring.cloud.nacos.config.file‐extension},即此例中则为加载:service1.yaml配置文件
PS:若未指定${spring.cloud.nacos.config.group}的值,则默认为DEFAULT_GROUP
(4) 分别编写客户端启动类(一样即可)
Service1App.java
package net.zhi365.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Xin.li
* @date 2021-01-10 12:02
*/
@SpringBootApplication
public class Service1App {
public static void main(String[] args) {
SpringApplication.run(Service1App.class, args);
}
}
Service2App.java
package net.zhi365.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author Xin.li
* @date 2021-01-10 12:02
*/
@SpringBootApplication
public class Service2App {
public static void main(String[] args) {
SpringApplication.run(Service2App.class, args);
}
}
PS:可能会出现Cannot access org.springframework.context.ConfigurableApplicationContext的错误,导致项目无法启动,此时删除掉Module中的iml文件,通过【File->New->Module from Existing Sources…】重新导入一次就可以了~
(5) 查看监听
启动Service1App与Service2App后,可以通过Nacos的管理控制台的监听查询页通过IP地址进行查询,如下图:
5.2.4 使用@Value获取配置信息
(1) 在Service1模块中编写ValueController.java
package net.zhi365.service.web;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Xin.li
* @date 2021-01-10 13:39
*/
@RestController
@RequestMapping("value")
public class ValueController {
@Value("${common.name}")
private String commonName;
@GetMapping("/getCommonName")
public String getCommonName() {
return this.commonName;
}
}
(2) 访问ValueController
打开浏览器输入地址:http://localhost:5601/value/getCommonName得到配置信息
PS:但是使用@Value注解获取配置信息会有无法动态接收配置文件更新的问题
5.2.5 使用ConfigurableApplicationContext实现动态更新
(1) 在Service2模块中编写ConfigurableApplicationContextController.java
package net.zhi365.service.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Xin.li
* @date 2021-01-10 13:47
*/
@RestController
@RequestMapping("cacc")
public class ConfigurableApplicationContextController {
// 注入配置文件上下文
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping(value = "/getCommonName")
public String getCommonName(){
return applicationContext.getEnvironment().getProperty("common.name");
}
}
(2) 访问页面ConfigurableApplicationContextController
打开浏览器输入地址:http://localhost:5602/cacc/getCommonName得到配置信息
(3) 在Nacos控制台修改配置文件
(4) 刷新页面发现配置信息已同步
5.2.6 自定义Namespace与Group配置
在未指定${spring.cloud.nacos.config.namespace}时,默认使用的是Public命名空间。若需使用自定义的命名空间,需通过以下配置来实现:
spring:
cloud:
nacos:
config:
namespace: 470cd824-4b0a-4001-bcac-8491cf2987f8 # 命名空间
在未指定${spring.cloud.nacos.config.group}时,默认使用的是DEFAULT_GROUP组。若需使用自定义的组,需通过以下配置来实现:
spring:
cloud:
nacos:
config:
group: DEFAULT_GROUP # 组
5.2.7 自定义扩展配置文件
Spring Cloud Alibaba Nacos Config支持同一服务可加载多个配置文件,具体操作如下:
(1) 在Nacos控制台上新建ext-age.yaml配置文件
common:
age: 30
(2) 在Nacos控制台上新建ext-location配置文件
common:
location: 昆山
注:若不配置Data ID的扩展名在启动Spring Boot时则会报出异常,应该是配置文件虽然可以找到,但是无法确定按哪个格式进行解析,同时配置项也无法读出。
修改如下:
(3) 在Nacos控制台上新建ext-fullname配置文件
common:
fullname: LeoLee
(4) 修改Service2的bootstrap.yml添加扩展配置信息
server:
port: 5602 # 启动端口 命令行注入
spring:
application:
name: service2
cloud:
nacos:
config:
server‐addr: localhost:8848 # 配置中心地址
file‐extension: yaml
namespace: 470cd824-4b0a-4001-bcac-8491cf2987f8 # 开发环境
group: DEFAULT_GROUP # 默认组
# ext-age.yaml在默认组中,所以可以不写组名
extension-configs[0]:
data-Id: ext-age.yaml
refresh: true
# ext-location.yaml在GLOBAL_GROUP组中,需要写组名
extension-configs[1]:
data-Id: ext-location.yaml
group: GLOBAL_GROUP
# ext-fullname.yaml未开启自动更新
extension-configs[2]:
data-Id: ext-fullname.yaml
(5) 在Service2中新增ExtConfig.java
package net.zhi365.service.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Xin.li
* @date 2021-01-10 15:00
*/
@RestController
@RequestMapping("config")
public class ExtConfig {
// 注入配置文件上下文
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping(value = "/extConfig")
public String getExtConfig() {
StringBuffer configInfo = new StringBuffer(applicationContext.getEnvironment().getProperty("common.name"));
configInfo.append(applicationContext.getEnvironment().getProperty("common.age"));
configInfo.append(applicationContext.getEnvironment().getProperty("common.location"));
configInfo.append(applicationContext.getEnvironment().getProperty("common.fullname"));
return configInfo.toString();
}
}
(6) 重启项目并访问页面
http://localhost:5602/config/extConfig/
(7) 在Nacos控制台修改,ext-age.yaml与ext-fullname.yaml信息如下:
ext-age.yaml
common:
age: 40
ext-fullname.yaml
common:
fullname: Leo
(8) 再次刷新页面
发现ext-age.yaml的信息由于配置了refresh: true进行了动态更新,而ext-fullname.yaml的信息没有改动
5.2.8 自定义共享配置文件
(1) 修改Service1的bootstrap.yml文件
server:
port: 5601 # 启动端口 命令行注入
spring:
application:
name: service1
cloud:
nacos:
config:
server‐addr: localhost:8848 # 配置中心地址
file‐extension: yaml
namespace: 470cd824-4b0a-4001-bcac-8491cf2987f8 # 开发环境
group: DEFAULT_GROUP # 默认组
# 共享配置
shared-configs: ext-age.yaml, ext-location.yaml, ext-fullname.yaml
shared-configs的方式支持配置多个配置文件,中间使用“,”号隔开
(2) 将刚刚Service2中的ExtConfig复制到Service1中,并重启Service1程序
package net.zhi365.service.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Xin.li
* @date 2021-01-10 15:00
*/
@RestController
@RequestMapping("config")
public class ExtConfig {
// 注入配置文件上下文
@Autowired
private ConfigurableApplicationContext applicationContext;
@GetMapping(value = "/extConfig")
public String getExtConfig() {
StringBuffer configInfo = new StringBuffer(applicationContext.getEnvironment().getProperty("common.name"));
configInfo.append(applicationContext.getEnvironment().getProperty("common.age"));
configInfo.append(applicationContext.getEnvironment().getProperty("common.location"));
configInfo.append(applicationContext.getEnvironment().getProperty("common.fullname"));
return configInfo.toString();
}
}
(3) 访问页面,发现结果如下:
由于ext-location.yaml为GLOBAL_GROUP组,而非默认组(即DEFAULT_GROUP)中配置文件,所以共享配置的方式无法对其进行加载
(4) 修改ext-age.yaml与ext-fullname.yaml中配置信息如下
ext-age.yaml
ext-fullname.yaml
(5) 刷新页面,得到如下结果
发现共享配置也并未同步数据,原来的refreshable-dataids配置项目在1.4.0中被删除
5.2.9 配置的优先级
Spring Cloud Alibaba Nacos Config 目前提供了三种配置方式从 Nacos 拉取相关的配置。
A: 通过 spring.cloud.nacos.config.shared-configs 支持多个共享 Data Id 的配置
B: 通过 spring.cloud.nacos.config.ext-config[n].data-id 的方式支持多个扩展 Data Id 的配置,多个Data Id 同时配置时,他的优先级关系是 spring.cloud.nacos.config.ext-config[n].data-id 其中 n 的值越大,优先级越高。
C: 通过内部相关规则(应用名、扩展名 )自动生成相关的 Data Id 配置
当三种方式共同使用时,他们的一个优先级关系是:C > B >A
(1) 修改ext-fullname配置文件如下:
(2) 重启Service2程序,查看页面
http://localhost:5602/config/extConfig/
由于配置文件顺序关系,ext-fullname.yaml中的age信息,覆盖掉了ext-age.yaml中的age信息
(3) 同样,如果配置service1.yaml中的age信息,则会覆盖掉extension-configs中关于age的配置信息,测试如下:
5.2.10 关闭配置
通过${spring.cloud.nacos.config.enabled}为false可以关闭Spring Cloud Nacos Config
关闭配置后,再访问extConfig则报服务器内部错误~