使用Maven Profile和nacos namespace+group实现环境隔离


遇到的问题

  1. 在开发过程中需要修改服务的nacos地址(或其他公共配置)时,需要每个微服务配置文件都改一遍
  2. 几乎nacos每个微服务的配置文件中都含有相同的配置(例如数据库配置),当需要修改数据库连接地址时每个nacos配置文件都改一遍
  3. 在不同的项目中会存在相同的模块名(global-auth),会有nacos的Data ID重复的情况
  4. 对应不同的环境应有多套配置文件(如测试环境、开发环境、linux环境和windows环境等等)
  5. 如何在不改动代码的情况下快速发布、部署多个环境下的代码

解决问题

使用Nacos Namespace进行多环境配置

首先,nacos为我们提供了多种环境隔离的方案,可以根据项目规模、参与开发人数和业务规划等多个角度可以确定我们的最优方案

第一种:通过Data ID与profile实现。

优点:这种方式与Spring Cloud Config的实现非常像,用过Spring Cloud
Config的用户,可以毫无违和感的过渡过来,由于命名规则类似,所以要从Spring Cloud Config中做迁移也非常简单。
缺点:这种方式在项目与环境多的时候,配置内容就会显得非常混乱。配置列表中会看到各种不同应用,不同环境的配置交织在一起,非常不利于管理。
建议:项目不多时使用,或者可以结合Group对项目根据业务或者组织架构做一些拆分规划。
第二种:通过Group实现。

优点:通过Group按环境讲各个应用的配置隔离开。可以非常方便的利用Data
ID和Group的搜索功能,分别从应用纬度和环境纬度来查看配置。
缺点:由于会占用Group纬度,所以需要对Group的使用做好规划,毕竟与业务上的一些配置分组起冲突等问题。
建议:这种方式虽然结构上比上一种更好一些,但是依然可能会有一些混乱,主要是在Group的管理上要做好规划和控制。
第三种:通过Namespace实现。

优点:官方建议的方式,通过Namespace来区分不同的环境,释放了Group的自由度,这样可以让Group的使用专注于做业务层面的分组管理。同时,Nacos控制页面上对于Namespace也做了分组展示,不需要搜索,就可以隔离开不同的环境配置,非常易用。
缺点:没有啥缺点,可能就是多引入一个概念,需要用户去理解吧。
建议:直接用这种方式长远上来说会比较省心。虽然可能对小团队而言,项目不多,第一第二方式也够了,但是万一后面做大了呢?
参考文章:Nacos配置细化

过程不再讨论,这里直接说结论:
Namespace区分环境
Group区分项目
Data ID区分服务,不再使用profiles
在这里插入图片描述

Nacos开启shared-configs配置共享,读取多个配置

在实际项目中,每个子模块中,spring有许多相同配置项,比如Redis,Mysql等等,这些公用配置信息,可以放在同一个配置文件中,方便管理及修改

将数据库连接和其他公共配置,分别放在两个yml文件中

# 1.公共配置
  shared-configs[0]:
  data-id: application.${spring.cloud.nacos.config.file-extension} # 配置文件名-Data Id
  group: ${nacos.group}   # 默认为DEFAULT_GROUP
  refresh: true   # 是否动态刷新,默认为false
# 2.数据库配置
shared-configs[1]:
  data-id: datasource.${spring.cloud.nacos.config.file-extension}
  group: ${nacos.group}
  refresh: true

使用Maven Profile实现项目内的环境统一

​ 在开发过程中,我们的项目会存在不同的运行环境,比如开发环境、测试环境、生产环境,而我们的项目在不同的环境中,有的配置可能会不一样,比如数据源配置、日志文件配置、以及一些软件运行过程中的基本配置,那每次我们将软件部署到不同的环境时,都需要修改相应的配置文件,这样来回修改,很容易出错,而且浪费劳动力。

​ 我们使用Maven Profile来让微服务的配置项变成一个动态参数,在pom文件中进行统一维护,可以让多个微服务的配置进行同步修改。首先,添加的你的多环境配置参数,修改项目父pom文件,pom文件新增配置如下:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
    </resources>
</build>
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <nacos.namespace>dev</nacos.namespace>
            <nacos.group>HIM_GROUP</nacos.group>
            <nacos.server-addr>127.0.0.1:8838</nacos.server-addr>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <nacos.namespace>prod</nacos.namespace>
            <nacos.group>HIM_GROUP</nacos.group>
            <nacos.server-addr>192.168.3.10:8838</nacos.server-addr>
        </properties>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <nacos.namespace>test</nacos.namespace>
            <nacos.group>HIM_GROUP</nacos.group>
            <nacos.server-addr>192.168.3.10:8838</nacos.server-addr>
        </properties>
    </profile>
</profiles>

bootstrap.yml文件的配置修改如下:

# Spring
spring:
  application:
    # 应用名称
    name: global-gateway
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: ${nacos.server-addr}
        group: ${nacos.group}
        namespace: ${nacos.namespace}

bootstrap.yml文件中对应的${nacos.server-addr}等即为pom.xml文件的配置值

其中pom.xml文件中的activation标签代表当前启用的环境,打包时会默认打包activation所标记的环境
使用maven打包时可以通过 -P 参数来指定环境
例如:

mvn clean package -P test

以上打包命令表示使用测试环境进行打包,这样就可以实现使用打包命令而不改动代码对多个环境进行发布

当你想打包的环境信息不在pom文件中时,你还可以通过mvn -Dxxx来指定maven的打包参数
例如:

mvn -Dnacos.server-addr=127.0.0.1:8848 -Dnacos.namespace=prod  clean package

总结:

好了,刚刚我们列出了三种打包方式

  1. mvn clean package

  2. mvn clean package -P test

  3. mvn -Dnacos.server-addr=127.0.0.1:8848 -Dnacos.namespace=prod clean package

第一种会使用activation标签所标记位置的参数打包(上面的例子中是dev环境)

第二种会使用-P 参数指定的的环境名进行打包

第三种会直接使用指定的配置进行打包

注:当使用-P 指定环境后,activation标签不再生效

当使用-D 指定具体参数时,对于已指定参数,前两种方法也不再生效

优先级:-D 指定具体参数 > -P 指定环境 > activation标签

结语

使用Nacos Namespace配置解决了问题3和4
shared-configs配置解决了问题2
Maven Profile解决了问题1和5

global-auth服务的完整配置:

# Spring
spring:
  application:
    # 应用名称
    name: global-auth
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: ${nacos.server-addr}
        group: ${nacos.group}
        namespace: ${nacos.namespace}
      config:
        # 配置中心地址
        server-addr: ${nacos.server-addr}
        # 配置文件格式
        file-extension: yml
        group: ${nacos.group}
        namespace: ${nacos.namespace}
        # 1.公共配置
        shared-configs[0]:
          data-id: application.${spring.cloud.nacos.config.file-extension} # 配置文件名-Data Id
          group: ${nacos.group}   # 默认为DEFAULT_GROUP
          refresh: true   # 是否动态刷新,默认为false
        # 2.数据库配置
        shared-configs[1]:
          data-id: datasource.${spring.cloud.nacos.config.file-extension}
          group: ${nacos.group}
          refresh: true

参考文章:https://blog.csdn.net/jav_zhangwei/article/details/109728425?spm=1001.2014.3001.5501


文章作者: witleo
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 witleo !
  目录