写在前面的文章
在前面的文章中,我们已经学会了如何加载 Nacos 中的配置,但是提到配置,就不得不关注一个问题:多环境管理如何实现。
在 SpringBoot 项目中,可以通过
spring.profiles.active
配置项配置当前项目的环境
简述
在软件开发流程中,最基本需要经历 开发 > 测试 > 生产 等几个步骤,其中测试还要分 sit测试、uat测试、压力测试等,每个步骤都可能会存在相同的配置项,但是需要配置不同的配置值。
以数据库为例,开发数据库供开发人员使用及自测,测试数据库供测试人员使用,生产数据库供线上使用。对于程序来说,只需要对数据源进行操作,而数据源具体连接哪个数据库,则完全由配置值进行限定。
所谓多环境管理,就是为每个环境准备一套配置文件,在相应环境部署应用时,读取相应的配置文件即可,这些对于程序而言是透明的,从而达到一套代码,根据环境配置,获得不同实现。
使用 profile 实现多环境管理
在上一篇文章最后的扩展中讲到 DataId = {prefix}.{file-extension}
,其实并不完整,DataId 的组成还有一部分,就是 profile。
完整的规则是
${spring.cloud.nacos.config.prefix}-${spring.profile.active}.
${spring.cloud.nacos.config.file-extension}
因为上一篇文章中的示例中,没有设置 spring.profile.active
,所以就被简化了。
本文将分别设置 spring.profile.active
为 dev 与 test,实现应用自动加载 Nacos 中不同的配置文件。
实战
第一步:在 Nacos 管理后台创建两个配置文件
两个文件的 DataId 分别为 nacos-config-profile-dev.yaml
与 nacos-config-profile-test.yaml
,Group 都为 NACOS_PROFILE
,
配置格式都选择为 yaml
,内容配置项都为 course.title
,配置值分别为 nacos-dev
与 nacos-test
,
这样,应用加载到不同的文件时,输出的值就会不一样。
第二步:创建 SpringBoot 应用,名称为 nacos-config-profile
,配置 spring.profiles.active
为 dev
如果不知道如何创建一个 Nacos 配置中心的客户端应用,请参考上一篇文章
配置文件 bootstrap.yml 内容如下
server:
port: 8084
spring:
application:
name: nacos-config-profile
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
prefix: ${spring.application.name}
file-extension: yaml
group: NACOS_PROFILE
profiles:
active: dev
第三步:启动应用
查看启动日志,可以看到加载的日志文件
Loading nacos data, dataId: 'nacos-config-profile-dev.yaml', group: 'NACOS_PROFILE'
第四步:修改 profile
为 test
,重启应用
查看启动日志,可以看到加载的日志文件
Loading nacos data, dataId: 'nacos-config-profile-test.yaml', group: 'NACOS_PROFILE'
思考
从上面的示例看出,实现多环境管理非常简单,只需要配置当前应用的 profile,应用就会自动加载相应 profile 名称的配置文件。
- 优点:与 SpringCloudConfig 配置一样,方便从 SpringCloudConfig 项目迁移过来
- 缺点:Nacos 面向的整个微服务,而不是单个应用,如果微服务数量很多,配置列表将会出现不同应用,不同环境交织在一起,维护将会变得困难
- 建议:服务数量少时使用
使用 namespace 实现多环境管理
为了让配置列表不那么太杂乱,最简单的办法就是把一个大的列表转换成 N 个小的列表,这样每一个列表就会显得整齐起来,这也是 namespace 的作用。
实战
第一步:在 Nacos 管理后台创建 namespace
根据 dev
及 test
两个环境创建两个相应的 namespace
namespace 的 ID 可以设置,也可以自动生成,后面配置需要用到,本例 ID 使用与名称一样的值
回到配置列表界面,可以看到左上角除了一直存在的 public 之外,出现了刚刚定义了 dev 及 test 两个标签页
其中 public 标签中可以看到之前创建的配置文件,而 dev 及 test 标签下则没有配置文件
第二步:在 dev 及 test 标签下分别创建配置文件
两个文件的 DataId 都为 nacos-config-profile.yaml
,Group 都为 NACOS_PROFILE
,
配置格式都选择为 yaml
,内容配置项都为 course.title
,配置值分别为 nacos-namespace-dev
与 nacos-namespace-test
,
第三步:在应用配置文件中添加 spring.cloud.nacos.config.namespace
配置项,内容填写 namespace 的 ID
示例:
server:
port: 8084
spring:
application:
name: nacos-config-profile
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
prefix: ${spring.application.name}
file-extension: yaml
group: NACOS_PROFILE
namespace: test
profiles:
active: test
第四步:启动应用
查看启动日志,可以看到加载的日志文件
Loading nacos data, dataId: 'nacos-config-profile.yaml', group: 'NACOS_PROFILE'
思考
通过 namespace
实现多环境配置简单易用,方便维护,也是官方推荐的方式。
不同的环境使用不同的 profile,如果通过修改配置文件的方式来修改 profile,需要在不同环境发布前先修改一次配置文件,
在发布脚本的启动命令中使用-Dspring.profiles.active=DEV
的方式来动态指定,会更加灵活。
多配置文件加载
在上面的示例中,我们已经实现了多环境加载,但是加载的是一整个配置文件,
实际项目中,不同环境之间会有一些配置是不同的,但是大部分配置是相同的,
比如只有数据源是不同的,其它配置是相同的,是不是可以只把数据源配置部分整成多环境加载,其它配置另外加载,
像 Quartz 之类可以考虑配置成一个独立的配置文件。
自带的多文件加载机制
在上例中,虽然我们设置的 profile 为 test,但是我们设置的 DataId 为 nacos-config-profile.yaml
,一样可以加载成功,
再创建一个 nacos-config-profile-test.yaml
配置文件,重启应用,可以看到日志里会显示两个配置文件都会被加载,带 profile 的后加载,相同的配置项会覆盖。
Loading nacos data, dataId: 'nacos-config-profile.yaml', group: 'NACOS_PROFILE'
Loading nacos data, dataId: 'nacos-config-profile-test.yaml', group: 'NACOS_PROFILE'
这其实跟 SpringBoot 的多环境配置文件加载是一样的
加载多个扩展配置文件
第一步:在当前配置的 namespace 下创建配置文件 common1.yaml
以及 common2.yaml
,group 都使用 DEFAULT_GROUP
第二步:通过配置 spring.cloud.nacos.config.ext-config
加载多个文件
properties 示例
spring.cloud.nacos.config.ext-config[0].data-id=common1.properties
spring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[0].refresh=true
spring.cloud.nacos.config.ext-config[1].data-id=common2.properties
spring.cloud.nacos.config.ext-config[1].group=DEFAULT_GROUP
spring.cloud.nacos.config.ext-config[1].refresh=true
yaml 完整示例:
server:
port: 8084
spring:
application:
name: nacos-config-profile
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
prefix: ${spring.application.name}
file-extension: yaml
group: NACOS_PROFILE
## 使用命名空间
namespace: test
## 配置多文件加载
ext-config:
- {dataId: common1.yaml,group: DEFAULT_GROUP,refresh: true}
- {dataId: common2.yaml,group: DEFAULT_GROUP,refresh: true}
profiles:
active: test
其中,refresh
参数控制这个配置文件中的内容是否支持自动刷新,默认情况下,只有默认加载的配置才会自动刷新,对于这些扩展的配置加载内容需要配置该设置时候才会实现自动刷新
第三步:启动应用,查看日志
Loading nacos data, dataId: 'common1.yaml', group: 'DEFAULT_GROUP'
Loading nacos data, dataId: 'common2.yaml', group: 'DEFAULT_GROUP'
Loading nacos data, dataId: 'nacos-config-profile.yaml', group: 'NACOS_PROFILE'
Loading nacos data, dataId: 'nacos-config-profile-test.yaml', group: 'NACOS_PROFILE'
加载共享配置
通过上面的示例已经实现了加载多个配置,不同应用共享配置。但是 Nacos 还提供了另外一个便捷的配置方式,比如下面的配置与上面使用的配置内容是等价的
spring.cloud.nacos.config.shared-dataids=common1.yaml,common2.yaml
spring.cloud.nacos.config.refreshable-dataids=common1.yaml,common2.yaml
共享模式下 group 只能使用 DEFAULT_GROUP
加载顺序
通过调试源码,可以看到如下代码
loadSharedConfiguration(composite);
loadExtConfiguration(composite);
loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);
所以默认会先加载共享配置,然后加载扩展配置,最后加载默认配置,默认配置可以使用多环境管理,从而实现静态配置+动态配置的组合配置模式。