文章目錄
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-{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來實現,建立多個形如{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進行項目分組,如下圖: