继上一篇 ​​微服务系列:Spring Cloud Alibaba 之 Nacos 注册中心​​ 学习之后,今天我们来学习 ​​Nacos​​ 的另一个重要特性: 配置中心

话不多说,开始今天的学习。

基本介绍

1. 什么是配置中心

在微服务架构中,当系统从一个单体应用,被拆分成分布式系统上一个个服务节点后,配置文件也必须跟着迁移(分割),这样配置就分散了,不仅如此,分散中还包含着冗余,如下图:

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_spring cloud alibaba

总得来说,配置中心就是一种统一管理各种应用配置的基础服务组件。

2. 为什么要使用配置中心

  • 配置实时生效:

传统的静态配置方式要想修改某个配置只能修改之后重新发布应用,要实现动态性,可以选择使用数据库,通过定时轮询访问数据库来感知配置的变化。轮询频率低感知配置变化的延时就长,轮询频率高,感知配置变化的延时就短,但比较损耗性能,需要在实时性和性能之间做折中。配置中心专门针对这个业务场景,兼顾实时性和一致性来管理动态配置。

  • 配置管理流程:

配置的权限管控、灰度发布、版本管
理、格式检验和安全配置等一系列的配置管理相关的特性也是配置中心不可获取的一部分。

配置中心将配置从各应用中剥离出来,对配置进行统一管理,应用自身不需要自己去管理配置。

3. Nacos 配置中心

​Nacos​​是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_spring_02

配置中心的服务流程如下:

1、用户在配置中心更新配置信息。
2、服务A和服务B及时得到配置更新通知,从配置中心获取配置。

下载方式

​nacos​​ 的下载方式和启动在上一篇 ​​微服务系列:Spring Cloud Alibaba 之 Nacos 注册中心​​ 文章中已描述,这里就不再赘述。

如何使用

1、添加依赖

<!-- springcloud alibaba nacos config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

2、在bootstrap.yml添加Nacos配置

server:
port: 9201

# Spring
spring:
application:
# 应用名称
name: cloud-nacos-provider
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

注意是 ​​bootstrap.yml​​​,
配置文件加载的优先级(由高到低)

bootstrap.properties ->bootstrap.yml -> application.properties -> application.yml

说明:之所以需要配置 ​​spring.application.name​​​ ,是因为它是构成 Nacos 配置管理 ​​dataId​​字段的一部分。

在 Nacos Spring Cloud 中,​​dataId​​ 的完整格式如下:

${prefix}-${spring.profiles.active}.${file-extension}
  • ​prefix​​​ 默认为 ​​spring.application.name​​​ 的值,也可以通过配置项 ​​spring.cloud.nacos.config.prefix​​来配置。
  • ​spring.profiles.active​​​ 即为当前环境对应的 profile,详情可以参考 ​​Spring Boot文档​​。 注意:当 spring.profiles.active 为空时,对应的连接符 ​-​ 也将不存在,dataId 的拼接格式变成 ​${prefix}.${file-extension}​,其实就算 ​spring.profiles.active​ 不为空,使用 ​${prefix}.${file-extension}​ 同样可以找到对应配置。
  • ​file-exetension​​​ 为配置内容的数据格式,可以通过配置项 ​​spring.cloud.nacos.config.file-extension​​​ 来配置。目前只支持 ​​properties​​​ 和 ​​yaml​​ 类型。

和同事一起开发项目的时候可以这样配置:

server:
port: 9211

# Spring
spring:
application:
# 应用名称
name: cloud-nacos-provider-ezhang # 此处后缀改成自己名字,防止和别人实例名一样出现负载均衡
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# 配置文件前缀
prefix: cloud-nacos-provider

配上 ​​spring.cloud.nacos.config.prefix​​​ 修改 ​​spring.application.name​​ 值为自己开发环境独有的,不和其他同事的实例名相同。但同时还需要在 gateway 网关中配置自己开发环境独有的路由

spring:
cloud:
gateway:
routes:
- id: cloud-nacos-provider-ezhang
uri: lb://cloud-nacos-provider-ezhang
predicates:
- Path=/ytb/**

3、在 nacos 控制台添加两个数据集(Data Id)

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_配置中心_03

  • ​application-dev.yml​​ 为共享配置

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_Nacos_04

  • ​cloud-nacos-provider-dev.yml​​ 为私有配置

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_java_05

4、编写测试类在Controller类中通过​@Value​注解获取配置值。

@RestController
@RequestMapping("/config")
@RefreshScope
public class ConfigController {

@Value("${ezhang.useConfig:false}")
private boolean useConfig;

@Value("${version}")
private String version;

@RequestMapping("/get")
public String get() {
String str1 = "共享配置:" + useConfig;
String str2 = "私有配置:" + version;
return str1 + "," +str2;
}

}

5、浏览器访问:http://localhost:9201/config/get

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_spring_06

返回正确数据表示测试通过。

动态刷新

相信你也注意到上面测试类中的 ​​@RefreshScope​​ 注解了,这个注解是 Spring Cloud 原生注解,是用来实现配置自动更新的。

测试类加上这个注解之后我们重新发布配置之后,就不用重启项目就可以自动更新了,当然,像是数据库连接这种的肯定还是需要重启项目的了。

我们改个配置试一下:

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_Nacos_07

发布后重新访问地址 ​​http://localhost:9201/config/get​

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_Nacos_08

配置已经自动更新了。

MySQL 支持

启动 ​​Nacos​​ 时我们可以看到这样一行日志:

Nacos started successfully in stand alone mode. use embedded storage

​use embedded storage​​ 表示使用的是内置数据源。

上面的这些配置都是存储在 ​​Nacos​​​ 自带的嵌入式数据库中的,不方便观察数据存储的基本情况,所以在 0.7 版本增加了支持 ​​MySQL​​ 数据源能力,具体的操作步骤:

  1. 安装数据库,版本要求:5.6.5+
  2. 初始化 mysql 数据库,数据库初始化文件:​​nacos-mysql.sql​
  3. 修改 ​​conf/application.properties​​ 文件,增加支持 mysql 数据源配置(目前只支持 MySQL ),添加 MySQL 数据源的 url、用户名和密码。
spring.datasource.platform=mysql

db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=nacos_devtest
db.password=youdontknow

这个​​application.properties​​​ 和 ​​nacos-mysql.sql​​​ 指​​nacos​​​的解压目录​​nacos/conf​​目录下的文件

再以单机模式启动 Nacos,Nacos 所有写嵌入式数据库的数据都写到了 MySQL。

控制台手册

官方文档:https://nacos.io/zh-cn/docs/console-guide.html

这个直接查看官方文档就好了,官方文档讲的也挺清楚了。

命名空间、分组、DataID

  • Namespace + Group + DataId 三者关系
    类似 Java 里面的 package 包名和类名,最外层的 Namespace 是可以用来区分部署环境的,Group 和 DataId 逻辑上区分两个目标对象。
  • 默认情况
    Namespace=public, Group=DEFAULT, 默认 Cluster 是 DEFAULT

1. 命名空间(​​Namespace​​)

1)什么是命名空间?

命名空间,即 Namespace,用于进行粗粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。

举个贴切的例子:

一个超市,内部有很多区域,比如零售休闲区、瓜果蔬菜区、生鲜区等等,顺着超市路标指引,我们如果买鱼,直接去生鲜区即可,我们买零食,直接去零食休闲区即可,买个东西无需在超市乱窜…这种区域划分呢,便是物以类聚,环境隔离的思想。我们 Nacos 的 Namespace 思想就如同超市中不同大类型的划分区域。

​Nacos​​ 中存在一个默认的命名空间 public,所有配置以及服务注册,在没有指定命名空间时都会默认从 public 这个命名空间拉取配置以及注册到该命名空间下的注册表中。

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_java_09

可以看到,我们之前的服务注册列表以及配置列表都在这个默认的命名空间 public 下。

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_java_10

2)命名空间的使用

我们来新建两个环境的命名空间 dev 和 test

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_配置中心_11

配置列表中就出现了两个 tab

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_java_12

我们把原来的配置克隆到新的命名空间下

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_java_13

然后需要我们在 ​​bootstrap.yml​​ 中配置一下使用的命名空间

server:
port: 9201

# Spring
spring:
application:
# 应用名称
name: cloud-nacos-provider
profiles:
# 环境配置
active: test
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 127.0.0.1:8848
# 服务注册到哪个命名空间
namespace: 91e42ae4-9596-42fb-a24d-5d71aea068c9
config:
# 配置中心地址
server-addr: 127.0.0.1:8848
# 服务从哪个命名空间拉取配置
namespace: 91e42ae4-9596-42fb-a24d-5d71aea068c9
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

增加 ​​spring.cloud.nacos.discovery.namespace​​​ 和 ​​spring.cloud.nacos.config.namespace​​​ 配置,值就是我们控制台创建时候生成的 ​​命名空间id​

我们这里是注册到了 test 命名空间下,启动项目会发现已成功注册。

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_spring cloud alibaba_14

test 命名空间下的 ​​cloud-nacos-provider-test.yml​​ 的配置如下:

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_配置中心_15

还是访问我们之前的测试接口 ​​http://localhost:9201/config/get​

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_spring cloud alibaba_16

3)注意事项

  • 同名的命名空间只能创建一个!
  • 微服务间如果没有注册到一个命名空间下,无法使用 OpenFeign 指定服务名负载通信(服务拉取的配置文件不同命名空间不影响)即服务间如果需要通信,则需要保证其 discovery 要在一个命名空间下(实际上一般都不会更改服务注册的命名空间)

2. 分组(​​Group​​)

Nacos 中的一组配置集(一个配置集就是一个配置文件),是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。

个人觉得 Group 类似于更细粒度一些的配置隔离。

举个通俗的例子:

我们还是用超市来举例,零食区中,薯片是放一个柜,糖是放一个柜;水产区,鲫鱼与鲫鱼是在一起的!基围虾和基围虾是放在一起的,这便是分组。

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_配置中心_17

配置步骤和上面命名空间配置类似,就不详细写下了。

注意事项

  • ​Group+DataId​​ 组合是唯一的,即同一分组下,不会出现多个相同 DataId 的配置;
  • ​Group​​ 间服务仍是隔离的,即服务注册到不同的分组时,无法使用 OpenFeign 指定服务名负载调用;
  • ​Namespace+Group+DataId​​组合是唯一的,即不同命名空间下可有相同分组以及相同DataId,但同一个命名空间下Group与DataId则是唯一的。

PS:都看到这里了,点个赞吧,彦祖!

微服务系列:Spring Cloud Alibaba 之 Nacos 配置中心_配置中心_18