通过nacos官方文档的介绍,已经基本了解了nacos作为注册中心和配置中心的基本用法。
那么如果引入Nacos作为配置中心后,如何有效的进行配置的管理和不同环境间的隔离区分呢?
总的来说,多环境管理分三步:
以下将分别进行阐述。
一个应用为了在不同的环境下工作,常常会有不同的配置,代码逻辑处理。在实际开发中,通常一个系统会准备开发环境(dev)、测试环境(test)、预发环境(pre)、正式环境(prod)。
下面以开发环境(dev)和测试环境(test)为例,来示范引入nacos后的多环境管理。
我们通常使用profile来进行系统环境的标识,多个环境意味着有多个profile。不作指定时,profile默认为default,我们把指定profile的动作叫做激活。激活profile的方式有以下几种:
Spring在确定激活哪个profile时,需要依赖2个属性:
# 指定激活的环境为dev
spring.profiles.active=[指定环境名]
# 默认激活的环境
spring.profiles.default=[默认环境名]
Spring通常在application.xml中进行配置
SpringBoot通常在application.properties/application.yaml中进行配置
SpringCloud通常在bootstrap.properties/bootstrap.yaml中进行配置
springboot在本地调试时,可以在插件内配置激活的profile
通常mvn激活用来打指定环境的项目包。
step1:pom.xml加上profile信息:(profiles与build是同级的)
<profiles>
<profile>
<id>devid>
<properties>
<profiles.activation>devprofiles.activation>
properties>
<activation>
<activeByDefault>trueactiveByDefault>
activation>
profile>
<profile>
<id>testid>
<properties>
<profiles.activation>testprofiles.activation>
properties>
profile>
profiles>
Step2:在src/rescource加2个文件夹
test/xx.properties
dev/xx.properties
**Step3:**在pom的build配置项中编译打包过滤 2个环境的文件夹,并定义profile的变量
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<excludes>
<exclude>dev/*exclude>
<exclude>test/*exclude>
excludes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<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
jar/war在启动时,可选择启动参数激活的方式
# -D是设置系统属性值
java -jar app.jar -Dspring.profiles.active=dev
# springboot项目也可以用如下命令指定
java -jar app.jar --spring.profiles.active=dev
可以在系统环境变量中指定激活环境
# 编辑profile文件,
vi /etc/profile
# spring 环境激活
export SPRING_PROFILES_ACTIVE=dev
source /etc/profile
这几种激活方式的作用范围以及生效优先级是不同的,切勿在多个地方同时进行激活。
作用范围:环境变量>启动参数>mvn>配置
优先级:配置>mvn>启动参数>环境变量
提到环境隔离,一般会提到配置隔离、服务隔离、数据源隔离、日志隔离等,对应的分别是配置中心、注册中心、数据库和日志。nacos主要实现了配置中心和注册中心,故在这里主要讨论配置隔离和服务隔离。
配置上基于profile有两层区分实现,分别是spring层和nacos层。
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");
}
通过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"))
通过GroupId来实现,建立多个group,每个group表示一个环境。
springboot在application.properties中配置:
nacos.config.group=dev
或者在启动类上使用NacosPropertySource注解进行属性指定
@NacosPropertySource(dataId = "example", groupId = "dev")
通过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}")
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
jar/war包部署时,推荐启动参数激活方案。如多个jar部署到同一台服务器,使用启动参数激活,包之间互不影响。
镜像部署时,推荐环境变量激活方案。如打成docker镜像后上k8s集群,可以在部署时,deployment里指定ENV来激活,不同的镜像分别在不同的容器里,互不影响。
从一个租户的角度来看,如果有多套不同的环境,那么这个时候可以根据指定的环境来创建不同的 namespce,以此来实现多环境的隔离。
例如,你可能有dev,test和prod三个不同的环境,那么使用一套 nacos 集群可以分别建以下三个不同的 namespace。如下图所示:
通过定义不同的环境,不同环境的项目在不同的Namespace下进行管理,
不同环境之间通过Namespace进行隔离,项目间通过Group进行Namespace内的细化分组
这里以Namespace:dev为例,在Namespace中通过不同Group进行同一环境中不同项目的再分类
从多个租户的角度来看,每个租户可能会有自己的 namespace,每个租户的配置数据以及注册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。
例如超级管理员分配了三个租户,分别为张三、李四和王五。张三负责A项目,李四负责B项目,王五负责C项目
分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名空间。如下图所示:
当项目数<=环境数时,宜采用Group进行项目环境分组。
例如:张三负责A项目、B项目、C项目,每个项目又分了dev、test、prod三个环境,这时候在NameSpace中加入Group进行项目环境分组,如图:
当项目数>环境数时,宜采用Group进行项目分组。
例如:张三负责10多个项目,每个项目又分了dev、test、prod三个环境,这时候在NameSpace中加入Group进行项目分组,如下图: