springcloud3 指定 nacos 的服务名称和配置文件的 group,名称空间
一 指定读取微服务的配置文件
1.1 工程结构
1.2 nacos 的配置
1. 配置文件
2. 内容
1.3 微服务的配置文件
1.bootstrap.yml 内容
2.application.yml 文件内容
1.4 验证访问
控制台:
1.5 nacos 服务空间名称和 groupid 配置
1. 配置文件配置
2.nacos 的查看
一、组件版本关系
SpringCloudAlibaba、SpringCloud、SpringBoot对应版本
Spring Cloud Alibaba Version | Spring Cloud Version | Spring Boot Version |
---|---|---|
2021.0.1.0 |
Spring Cloud 2021.0.1 |
2.6.3 |
Nacos对应版本
Spring Cloud Alibaba Version | Sentinel Version | Nacos Version | RocketMQ Version | Dubbo Version | Seata Version |
---|---|---|---|---|---|
2021.0.1.0 |
1.8.3 |
1.4.2 |
4.9.2 |
2.7.15 |
1.4.2 |
官方提醒:每个 Spring Cloud Alibaba 版本及其自身所适配的各组件对应版本(经过验证,自行搭配各组件版本不保证可用)
更多版本对应关系参考:版本说明 Wiki
二、集成Nacos配置中心
1、SpringCloudAlibaba依赖
-
<dependencyManagement>
-
<dependencies>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-dependencies</artifactId>
-
<version>2.6.3</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-dependencies</artifactId>
-
<version>2021.0.1</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
<dependency>
-
<groupId>com.alibaba.cloud</groupId>
-
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
-
<version>2021.0.1.0</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
</dependencies>
-
</dependencyManagement>
2、启动配置管理
启动了 Nacos server 后,需要添加依赖
-
<dependency>
-
<groupId>com.alibaba.cloud</groupId>
-
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-
</dependency>
注意:版本 2.1.x.RELEASE 对应的是 Spring Boot 2.1.x 版本。版本 2.0.x.RELEASE 对应的是 Spring Boot 2.0.x 版本,版本 1.5.x.RELEASE 对应的是 Spring Boot 1.5.x 版本。
3、两种配置方式bootstrap.yml、spring.config.import
3.1 配置 bootstrap.yml
SpringCloudAlibaba2021.0.1.0版本移除了对bootstrap.yml支持。看spring-cloud-starter-alibaba-nacos-config依赖关系中虽然引入了spring-cloud-starter-bootstrap,但是不会生效,必须重新引入bootstrap的依赖
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-bootstrap</artifactId>
-
</dependency>
bootstrap.yml
-
spring:
-
application:
-
name: provider-server
-
cloud:
-
nacos:
-
config:
-
file-extension: yml
-
group: PROVIDER_CONFIG_GROUP
-
name: provider-server-dev.yml
-
shared-configs: #配置共享文件
-
- data-id: application-common.yml
-
group: PROVIDER_CONFIG_GROUP
-
refresh: true
-
- data-id: application-custom.yml
-
group: PROVIDER_CONFIG_GROUP
-
refresh: false
Nacos配置中心文件
在 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}
file-exetension
为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension
来配置。目前只支持properties
和yaml
类型。
provider-server-dev.yml
application-custom.yml
application-common.yml
这个配置是共享文件,这里配置redis缓存
-
spring:
-
redis:
-
# Redis默认情况下有16个分片,这里配置具体使用的分片。默认是索引为0的分片
-
database: 1
-
# Redis服务器地址
-
host: 127.0.0.1
-
# Redis服务器连接端口
-
port: 6379
-
# Redis服务器连接密码(默认为空)
-
password: 123456
-
# 连接超时时间(毫秒)
-
timeout: 2000s
-
-
# 配置文件中添加 lettuce.pool 相关配置,则会使用到lettuce连接池
-
lettuce:
-
pool:
-
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
-
max-wait: 60s
-
# 连接池中的最大空闲连接 默认 8
-
max-idle: 10
-
# 连接池中的最小空闲连接 默认 0
-
min-idle: 10
-
# 连接池最大连接数(使用负值表示没有限制) 默认 8
-
max-activ: 8
-
3.2 spring.config.import方式
使用这个方法时,不需要bootstrap.yml。如果引用了 spring-cloud-starter-bootstrap需要去除
创建application.yml
-
server:
-
port: 8090
-
-
spring:
-
application:
-
name: provider-server
-
cloud:
-
nacos:
-
discovery:
-
group: PROVIDER_GROUP
-
config:
-
group: PROVIDER_CONFIG_GROUP
-
server-addr: 127.0.0.1:8848
-
config:
-
import:
-
- optional:nacos:provider-server-dev.yml # 监听 PROVIDER_GROUP :provider-config-dev.yml
-
# - optional:nacos:provider-server-dev.yml?group=group_01 # 覆盖默认 group,监听 group_01:provider-config-dev.yml
-
# - optional:nacos:provider-server-dev.yml?group=group_02&refreshEnabled=false # 不开启动态刷新
-
- nacos:provider-server-dev.yml # 在拉取nacos配置异常时会快速失败,会导致 spring 容器启动失败
4、通过 Spring Cloud 原生注解 @RefreshScope
实现配置自动更新
读取配置文件有两种方式:
1、直接通过@Value注解
2、通过实体类注入
UserConfig.java
其中prefix = "configdata"是application-custom.yml配置文件内容的前缀
-
-
-
-
public class UserConfig {
-
private String name;
-
private Integer age;
-
private String id;
-
}
-
-
-
-
public class ProviderController {
-
-
-
private UserConfig userConfig;
-
-
-
private StringRedisTemplate redisTemplate;
-
-
-
private String port;
-
-
-
public String providerTest() {
-
return "我是provider,已成功获取nacos配置中心的数据:(name:" + userConfig.getName() +",age:"+userConfig.getAge()+",id:"+userConfig.getId()+")";
-
}
-
-
-
public void addRedisValue(){
-
redisTemplate.opsForValue().set("zhangsan","23");
-
}
-
-
-
public String getPort() {
-
return "我是provider,已成功获取nacos配置中心的数据:(端口号:" +port +")";
-
}
-
}
5、演示
1、@Value注解
2、实体类
修改配置并且发布
验证动态刷新完成
一、前言
用过 SpringCloudAlibaba 的小伙伴都知道 nacos 的配置有一个 namespace 和 group 的概念,这两个概念的字面意思都很容易理解,但是实际项目中使用起来,却不是那么回事了。
这就好比,你面试的时候问一个人,分布式事务的解决方式有哪些,他可能会告诉你两阶段提交、三阶段提交等等,然后针对各个方式是如何实现的、原理是什么,说的也很清楚。
这个时候你如果问题,那如何落地呢?
不少人,此时就会傻眼了!
你是不是这个样子呢?
那这个 namespace 和 group 其实和上面我们讲解的小案例是同样的道理,只不过 namespace 和 group 实际落地也简单一些,只是规范与否的问题。
有些小伙伴可能会讲,稍微不那么规范也没啥问题,就像我们代码中一般不能有魔法值,但是大多数项目都会有的,甚至不少知名开源项目也是如此。
有这个思路的小伙伴,说明是真的有在思考,恭喜你!
我们拿代码中的魔法值和 namespace 与 group 的问题来说一说。
魔法值的优点是:
- 简单、便捷;
- 开发效率高;
- 直观,一眼就知道这是个什么东西。
缺点:
- 维护性差,一旦有修改,需要查找并一一修改;
- 不够优雅;
- 维护时容易出错。
魔法值的优缺点大体如此,不必较真。
其实我们看魔法值的问题,真的不是很大。但是 namespace 和 group 的话就不一定了。
二、namespace 和 group 的不规范
如果是小公司小团队,或者说少数几个项目有自己独立的 nacos,那怎么玩都影响不大,这个其实就和我们平时自己玩的 demo 基本一个调子,只不过项目中的更真实一点而已。
但是如果真的是在生产上使用,而且是整个公司的 nacos 集群的话,而且不是小项目、小团队的话,这个就有必要认真考虑一下了。因为一旦规范定下来了,后面再变更,是一个很麻烦的事情,整个公司的项目都要跟着做变更,你未必能说服领导或者说服对方配合你,那你就 gg 了。
如果不规范,会产生一些问题,会比较麻烦,后面我们慢慢说。
因为公司最近再做这一块,本人原本对 namespace 和 group 的理解也不是很深入,总觉得公司的这个做法有问题,所以就网上看了不少文章,查阅了资料,算是有一些个人的看法,以飨诸位小伙伴。
网上那种不适合多项目、多环境的配置我们就不说了,我们只说适合生产的多项目、多环境的配置方式。
三、我的评论
这里有一篇文章,讲解的不错,但是也未必是很准确。
https://blog.csdn.net/m0_54852680/article/details/122170936
在这篇文章中,我给出了我的看法,放在下面。
关于 nacos 的多环境多项目的问题,网上很多说的都不到位,或者说,根本不具备实际生产使用的方式。
这篇文章整体上还是说的比较清楚的,重要的是生产上使用也没啥大问题,而网上很多文章讲的也就是自己玩的 demo 而已,生产上根本用不了。
不过这里有个问题,多租户多环境多项目的情况下,namespace 以租户名字命名的方式个人感觉不是一个很好的方式,在 nacos 上的配置管理页面上,命名空间是一栏显示的,如果是以租户名字显示,如果公司人多,项目多,会有很多,根本难以显示出来,而且到时候会很难查找。我对租户的理解不深入,不敢妄加评论,不知道是否合理?
个人感觉,以 namespace 来区分不同环境,以 group 来区分不同项目或者说项目组最合适。区分环境这个不说了。区分项目的或项目组的,可以建一个项目组的分组,里面存放的不一定只是这一个项目,而是一组项目,比如一个具体某一块业务拆分成多个项目,那么这几个项目可以放在一个分组下。其他的比如,网关、用户鉴权等可以放一个分组,一些基础功能模块按照业务逻辑分为不同的分组,领完如果公司业务比较多,可以分不同的分组。这样下来,一、命名空间不会太多,方便查看每个命名空间下的配置或服务;二、事先建好命名空间,不来回变动,也剩的来回折腾;三、在查找不同的配置时可以通过分组来查找,或者直接 dataId 查找,也方便;四、查看不同服务时,可以通过服务名称或分组,同三是一样的道理。
至于文章中说的,多租户的情况,一个人负责很多个项目,那每个人负责的项目他自己肯定清楚的,有了不同的 namespace,他就可以去对应的环境找到对应的项目去测试,解决问题。
至于有人担心的,项目多了,在某一个指定环境,比如 uat 环境,会担心不方便。其实这个完全多余。首先,可以直接搜索对应的服务或 dataId,直接查找,也可以通过分组来查找,至于说多的问题,你管它干嘛,只看自己的就行了嘛!
文章中说的以租户的名字来命名空间的,还有个问题,这是要写到代码中的,张三来了,建一个,等张三走了,李四来了,也要建一个吗?那项目已经上线的张三这个命名空间咋办呢?到时候项目运行几年得多少啊?如果说不新建,让李四用张三的,那李四负责的项目未必就和张三负责的一样多,到时候一样混乱。不知道作者怎么看?还有,把人名写在项目中,这个。。。
四、官网
我们看 nacos 官网的说法。
1. 命名空间
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
一句话:不同环境的配置的区分隔。
2.Data ID
Data ID 通常用于组织划分系统的配置集。一个系统或者应用可以包含多个配置集,每个配置集都可以被一个有意义的名称标识。Data ID 通常采用类 Java 包(如 com.taobao.tc.refund.log.level)的命名规则保证全局唯一性。
3. 配置分组
Nacos 中的一组配置集,是组织配置的维度之一。通过一个有意义的字符串(如 Buy 或 Trade )对配置集进行分组,从而区分 Data ID 相同的配置集。当您在 Nacos 上创建一个配置时,如果未填写配置分组的名称,则配置分组的名称默认采用 DEFAULT_GROUP 。配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
一句话:默认 DEFAULT_GROUP,配置分组的常见场景:不同的应用或组件使用了相同的配置类型,如 database_url 配置和 MQ_topic 配置。
综合以上,我们得出结论:
通过 namespace 来区分不同的环境,通过 group 来区分不同的应用或组件或项目,通过 DataID 来区分不同的项目。
五、我的方案
结合我对本文引用的那篇文章的评论,个人看法如下面的表格:
DEV | SIT | UAT | PRD | ||||
服务 | 分组 | 服务 | 分组 | 服务 | 分组 | 服务 | 分组 |
a-service |
BIZ_ GROUP |
a-service |
BIZ_ GROUP |
a-service |
BIZ_ GROUP |
a-service |
BIZ_ GROUP |
b-service |
BASE_ GROUP |
b-service |
BASE_ GROUP |
b-service |
BASE_ GROUP |
b-service |
BASE_ GROUP |
c-service |
USER_ GROUP |
c-service |
USER_ GROUP |
c-service |
USER_ GROUP |
c-service |
USER_ GROUP |
d-service |
USER_ GROUP |
d-service |
USER_ GROUP |
d-service |
USER_ GROUP |
d-service |
USER_ GROUP |
e-service |
BIZ_ GROUP |
e-service |
BIZ_ GROUP |
e-service |
BIZ_ GROUP |
e-service |
BIZ_ GROUP |
下面我们就这个表格做一个解读。
第一行是 namespace,通过 DEV/SIT/UAT/PRD 来区分不同的环境,对应项目中 nacos 的 namespace。在 springboot2.6 之前,nacos 建议采用的是 bootstrap.yml 或 bootstrap.properties 方式进行 nacos 注册于发现的配置。
首先,在 bootstrap.properties 文件中指定环境
spring.profiles.active=dev
在 springboot2.4 之前是采用以上方式指定的,但是在 springboot2.4(含)以后,采用这种方式是不生效的,而是更改为了:
spring.config.activate.on-profile=dev
然后,在 bootstrap.properties 文件中指定 namespace 和 group
spring.cloud.nacos.discovery.namespace=${NACOS_NAMESPACE}
spring.cloud.nacos.config.namespace=${NACOS_NAMESPACE}
spring.cloud.nacos.config.group=${NACOS_GROUP:DEFAULT_GROUP}
以上三个,分别指的是服务发现的 namespace—— 也就是服务的 namespace、配置中心的 namespace、和配置的 group。
前两者一般我们设为一样的即可,对应我们上面表格的 DEV/SIT/UAT/PRD,以此来区分不同开发环境。
第三,我的做法
我这里采用了 ${NACOS_NAMESPACE} 的取值,是因为这个取值是在 pom 文件中自定义的,如下:
如果你项目中有定义四个开发环境,写四个 profile 即可。这样就不用写多个 properties 文件了,不管是 application.properties、application-dev.properties、application-sit.properties、application-uat.properties、application-prd.properties,或者是 bootstrap.properties、bootstrap-dev.properties、bootstrap-sit.properties、bootstrap-uat.properties、bootstrap-prd.properties。
这两种多环境的配置文件,完全不需要了。通过 pom 文件中单 profiles 标签定义多个 profile—— 也就是多个环境,然后在 bootstrap.properties 中配置对应的 profile 环境,然后加上对应的服务注册与发现的配置即可。
-
spring.profiles.active=dev
-
# spring.config.activate.on-profile=dev
-
-
spring.application.name=${artifactId}
-
spring.cloud.nacos.discovery.namespace=${NACOS_NAMESPACE}
-
spring.cloud.nacos.discovery.server-addr=${NACOS_ADDR}
-
spring.cloud.nacos.config.namespace=${NACOS_NAMESPACE}
-
spring.cloud.nacos.config.server-addr=${NACOS_ADDR}
-
# 本地启动服务,请使用DEV_GROUP
-
spring.cloud.nacos.config.group=${NACOS_GROUP:DEV_GROUP}
六、注意事项
1.namespace 指的是 id 不是名称。
如果不指定 id 的话自动生成一段字符串,建议配置好 id,这样在配置文件中也清楚,当前是哪个 namespace。
2. 取消了 bootstrap
另外,在最新版的 spring boot 上,bootstrap 这种方式的配置被取消了,而是采用了 application.yml 或 properties 的方式。
版本对应关系:
-
<dependencyManagement>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-dependencies</artifactId>
-
<version>2.6.3</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-dependencies</artifactId>
-
<version>2021.0.1</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
<dependency>
-
<groupId>com.alibaba.cloud</groupId>
-
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
-
<version>2021.0.1.0</version>
-
<type>pom</type>
-
<scope>import</scope>
-
</dependency>
-
</dependencyManagement>
以上是 SCA 官方给出的一个比较新的版本的对应关系。
以下内容来源官网
注意事项: spring-cloud-starter-alibaba-nacos-config
模块移除了 spring-cloud-starter-bootstrap
依赖,如果你想以旧版的方式使用,你需要手动加上该依赖,现在推荐使用 spring.config.import
方式引入配置
完成以上步骤就能无缝切换到 spring cloud alibaba 2021.0.1.0
版本
3. 新特性及其使用
支持 spring.config.import
这里假设有一个配置文件 (bootstrap.yml
),升级到新版本应该怎么配置呢
# bootstrap.yml
spring:
cloud:
nacos:
config:
name: test.yml
group: DEFAULT_GROUP
server-addr: 127.0.0.1:8848
extension-configs:
- dataId: test01.yml
group: group_01
- dataId: test02.yml
group: group_02
refresh: false
这两个配置是等价的
# application.yml
spring:
cloud:
nacos:
config:
group: DEFAULT_GROUP
server-addr: 127.0.0.1:8848
config:
import:
- optional:nacos:test.yml # 监听 DEFAULT_GROUP:test.yml
- optional:nacos:test01.yml?group=group_01 # 覆盖默认 group,监听 group_01:test01.yml
- optional:nacos:test02.yml?group=group_02&refreshEnabled=false # 不开启动态刷新
- nacos:test03.yml # 在拉取 nacos 配置异常时会快速失败,会导致 spring 容器启动失败
注意事项:
-
如果使用
spring.config.import
就不能使用 bootstrap.yml/properties 引入配置的方式了!!! -
如果引入了
spring-cloud-starter-alibaba-nacos-config
,并且使用 import 方式导入配置,项目启动时会自动检测是否引入了nacos:
条目,如果没有 import nacos 条目,会出现如下错误:
The spring.config.import property is missing a nacos: entry Action: Add a spring.config.import=nacos: property to your configuration. If configuration is not required add spring.config.import=optional:nacos: instead. To disable this check, set spring.cloud.nacos.config.import-check.enabled=false.
至此,关于新版本的改动的一些东西也说完了。
七、总结
正如我们在给本文引用的一篇文章写的评论说的那样。
- 多租户情况,本人不甚了解,不多置喙;
- 即便如此,如果以租户名字作为 namespace,也具有很多问题;
- namespace 用来做环境隔离,而非项目隔离,是比较好的方案;
- group 用来做项目或者一组项目的隔离,是比较合适的;
- 不同的 namespace 采用项目名 + 环境 + 后缀来区分,如,order-service-dev.yml,order-service-uat.yml 等;
- 以上所说都是在 nacos 上的配置文件和服务,而不是 springboot 项目中的配置文件;
- 采用了 nacos 之后,基本上配置文件就不怎么需要了,只需要一些 profile 环境、端口(其实也可以放到 nacos 上)、nacos 配置信息等,其余的配置都可以放到 nacos 上;
- 大多数配置项都可以放到 nacos 对应的服务名 + 环境的配置文件中,比如,order-service-dev.yml,但是可能这个项目还需要另外的配置文件,或者说老项目拆分后有多个配置文件,都在项目中使用,不便于合并到一个配置文件中,一样可以再建这些配置文件到 nacos 上,只是不是系统本身的配置文件,需要用到 nacos 的扩展配置文件或共享配置文件的配置。这个不在本文的讨论访问之内,感兴趣的可以自行百度。