文章目录
Nacos下的多环境管理
前言
通过nacos官方文档的介绍,已经基本了解了nacos作为注册中心和配置中心的基本用法。
那么如果引入Nacos作为配置中心后,如何有效的进行配置的管理和不同环境间的隔离区分呢?
总的来说,多环境管理分三步:
- 环境规划
- 环境指定
- 环境区分
以下将分别进行阐述。
一、环境规划
一个应用为了在不同的环境下工作,常常会有不同的配置,代码逻辑处理。在实际开发中,通常一个系统会准备开发环境(dev)、测试环境(test)、预发环境(pre)、正式环境(prod)。
下面以开发环境(dev)和测试环境(test)为例,来示范引入nacos后的多环境管理。
二、环境指定
我们通常使用profile来进行系统环境的标识,多个环境意味着有多个profile。不作指定时,profile默认为default,我们把指定profile的动作叫做激活。激活profile的方式有以下几种:
1、配置激活
Spring在确定激活哪个profile时,需要依赖2个属性:
# 指定激活的环境为dev
spring.profiles.active=[指定环境名]
# 默认激活的环境
spring.profiles.default=[默认环境名]
Spring通常在application.xml中进行配置
SpringBoot通常在application.properties/application.yaml中进行配置
SpringCloud通常在bootstrap.properties/bootstrap.yaml中进行配置
2、插件激活(仅本地有效)
springboot在本地调试时,可以在插件内配置激活的profile
3、mvn激活
通常mvn激活用来打指定环境的项目包。
step1:pom.xml加上profile信息:(profiles与build是同级的)
<profiles>
<profile>
<id>dev</id>
<properties>
<profiles.activation>dev</profiles.activation>
</properties>
<activation>
<!--默认为dev环境打包方式-->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profiles.activation>test</profiles.activation>
</properties>
</profile>
</profiles>
Step2:在src/rescource加2个文件夹
test/xx.properties
dev/xx.properties
**Step3:**在pom的build配置项中编译打包过滤 2个环境的文件夹,并定义profile的变量
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<!-- 排除dev、test目录下的文件 -->
<excludes>
<exclude>dev/*</exclude>
<exclude>test/*</exclude>
</excludes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<!-- 包含,若没有指定则默认为 activeByDefault 标签定义的profile -->
<includes>
<include>${profiles.activation}/*</include>
</includes>
</resource>
</resources>
**Step4:**自动化编译打包的指令为:(由参数 -P区分profile)
mvn clean install -Dmaven.test.skip=true -Pdev
mvn clean install -Dmaven.test.skip=true -Ptest
4、启动参数激活
jar/war在启动时,可选择启动参数激活的方式
# -D是设置系统属性值
java -jar app.jar -Dspring.profiles.active=dev
# springboot项目也可以用如下命令指定
java -jar app.jar --spring.profiles.active=dev
5、环境变量激活
可以在系统环境变量中指定激活环境
- 编辑profile文件
# 编辑profile文件,
vi /etc/profile
- 加入以下代码
# spring 环境激活
export SPRING_PROFILES_ACTIVE=dev
- 刷新使文件生效
source /etc/profile
提醒
这几种激活方式的作用范围以及生效优先级是不同的,切勿在多个地方同时进行激活。
作用范围:环境变量>启动参数>mvn>配置
优先级:配置>mvn>启动参数>环境变量
三、环境区分/隔离
提到环境隔离,一般会提到配置隔离、服务隔离、数据源隔离、日志隔离等,对应的分别是配置中心、注册中心、数据库和日志。nacos主要实现了配置中心和注册中心,故在这里主要讨论配置隔离和服务隔离。
1、配置区分
配置上基于profile有两层区分实现,分别是spring层和nacos层。
1.1 spring层区分
spring提供了两种区分粒度,分别是应用级粒度和代码级粒度。
应用级区分
应用级区分主要是通过application配置文件来实现。
application文件区分格式为:application- p r o f i l e . {profile}. profile.{file-extension},如application-dev.xml。
spring默认加载application.xml,在激活profile环境后还会加载指定环境的application文件。
-
profile=dev时
加载application.xml和application-dev.xml;
-
profile=test时
加载application.xml和application-test.xml;
通过在application.xml中进行公共配置,在application-dev.xml和application-test.xml中分别进行环境特定配置,可达到应用级环境隔离的目的。
代码级区分
代码级区分主要是通过profile注解和profile标签来实现。
在bean上使用profile注解或标签对类、方法或属性进行区分,如下:
/**
* 测试数据库
*/
@Component
@Profile("testdb")
public class TestDBConnector implements DBConnector {
@Override
public void configure() {
System.out.println("testdb");
}
}
/**
* 开发数据库
*/
@Component
@Profile("devdb")
public class DevDBConnector implements DBConnector {
@Override
public void configure() {
System.out.println("devdb");
}
1.2 nacos层区分
namespace级区分
通过NamespaceId来实现,建立多个namespace,每个namespace表示一个环境。
springboot在application文件中配置:
# 注意:此处配置的是namespace的ID,在nacos控制台可以找到
nacos.config.namespace=adbef7b1-711b-413a-baf7-6be032bc9b5a
或在启动类上使用EnableNacosConfig注解进行全局属性指定
@EnableNacosConfig(globalProperties = @NacosProperties(namespace = "adbef7b1-711b-413a-baf7-6be032bc9b5a"))
group级区分
通过GroupId来实现,建立多个group,每个group表示一个环境。
springboot在application.properties中配置:
nacos.config.group=dev
或者在启动类上使用NacosPropertySource注解进行属性指定
@NacosPropertySource(dataId = "example", groupId = "dev")
data级区分
通过DataId来实现,建立多个形如 p r e f i x − {prefix}- prefix−{spring.profile.active}的dataid,每个${spring.profile.active}表示一个环境。
springboot在application.properties中配置:
nacos.config.data-ids: config1-${spring.profile.active}.properties,config2-${spring.profile.active}.properties
或者在配置类上使用NacosConfigurationProperties注解进行指定
@NacosConfigurationProperties(dataId = "config1-${spring.profile.active}")
或者在启动类上使用NacosPropertySource注解进行指定
@NacosPropertySource(dataId = "config1-${spring.profile.active}")
2、服务区分
2.1 namespace级区分
nacos同样支持namespace对服务进行区分
springboot在application.properties中配置:
# 注意:此处配置的是namespace的ID,在nacos控制台可以找到
nacos.discovery.namespace=adbef7b1-711b-413a-baf7-6be032bc9b5a
接入dubbo时,改用如下配置:
# 配置注册中心地址和命名空间
dubbo.registry.address=nacos://${nacos.ip}:${nacos.port}?namespace=adbef7b1-711b-413a-baf7-6be032bc9b5a
2.2 group级区分(暂不支持)
四、建议实施方案
1、环境指定方案
1.1 包部署方案
jar/war包部署时,推荐启动参数激活方案。如多个jar部署到同一台服务器,使用启动参数激活,包之间互不影响。
1.2 镜像部署方案
镜像部署时,推荐环境变量激活方案。如打成docker镜像后上k8s集群,可以在部署时,deployment里指定ENV来激活,不同的镜像分别在不同的容器里,互不影响。
2、环境区分方案
2.1 单租户方案
从一个租户的角度来看,如果有多套不同的环境,那么这个时候可以根据指定的环境来创建不同的 namespce,以此来实现多环境的隔离。
例如,你可能有dev,test和prod三个不同的环境,那么使用一套 nacos 集群可以分别建以下三个不同的 namespace。如下图所示:
通过定义不同的环境,不同环境的项目在不同的Namespace下进行管理,
不同环境之间通过Namespace进行隔离,项目间通过Group进行Namespace内的细化分组
这里以Namespace:dev为例,在Namespace中通过不同Group进行同一环境中不同项目的再分类
2.2 多租户方案
从多个租户的角度来看,每个租户可能会有自己的 namespace,每个租户的配置数据以及注册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。
例如超级管理员分配了三个租户,分别为张三、李四和王五。张三负责A项目,李四负责B项目,王五负责C项目
分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名空间。如下图所示:
当项目数<=环境数时,宜采用Group进行项目环境分组。
例如:张三负责A项目、B项目、C项目,每个项目又分了dev、test、prod三个环境,这时候在NameSpace中加入Group进行项目环境分组,如图:
当项目数>环境数时,宜采用Group进行项目分组。
例如:张三负责10多个项目,每个项目又分了dev、test、prod三个环境,这时候在NameSpace中加入Group进行项目分组,如下图: