Nacos六多环境下如何管理及隔离配置和服务

26次阅读

共计 6879 个字符,预计需要花费 18 分钟才能阅读完成。

前言

前景回顾:

  • Nacos(五):多环境下如何“读取”Nacos 中相应环境的配置
  • Nacos(四):SpringCloud 项目中接入 Nacos 作为配置中心

现如今,在微服务体系中,一个系统往往被拆分为多个服务,每个服务都有自己的配置文件,然后每个系统往往还会准备开发环境、测试环境、正式环境

我们来说算一算,假设某系统有 10 个微服务,那么至少有 10 个配置文件吧,三个环境(devtestprod),那就有 30 个配置文件需要进行管理。

这么多的配置文件,要修改一个或者多个的时候,稍有不慎可能就会出现改错了、不生效 …. 等等问题。

那么如果引入 Nacos 作为配置中心后,如何有效的进行配置文件的管理和不同环境间的隔离区分呢?

别担心,Namespace 可以帮助我们进行多环境下的管理和隔离

有了上一篇文章的介绍,本文主要从以下几个方面介绍:

  • Namespace 是什么
  • Namespace 如何进行配置和服务的管理、隔离
  • 创建和获取 NamespaceID
  • Namespace 实施方案 1
  • Namespace 实施方案 2

Namespace

Nacos 引入了命名空间 (Namespace) 的概念来进行 多环境配置和服务 的管理及隔离

Namespace 也是官方推荐的多环境支持方案。

如何进行配置和服务的管理、隔离

当我们的服务达到一定的数量,集中式的管理许多服务会十分不便,

那我们可以将这些具有相同特征或属性的服务进行分组管理,服务对应的配置也进行分组隔离

这里的 分组 就是 Namespace 的概念,将服务和配置纳入相同的 Namespace 进行管理

不同 Namespace 下的服务和配置之间就隔离开来

创建和获取 NamespaceID

NamespaceId 值是在配置文件配置时必须要填入的配置项,所以需要我们先创建 Namespace 和 Id,步骤如下:

nacos 的控制台左边功能栏看到有一个 命名空间 的功能,点击就可以看到 新建命名空间 的按钮

新建成功后,可以在命名空间列表中查看到你所创建的 Namespace 和他生成的 ID 值

这里只是讲解创建步骤,本文继续延用 Nacos(五)中创建的DEV、TEST

Namespace 实施方案 1

Nacos 给出了两种 Namespace 的实践方案

  • 面向一个租户
  • 面向多个租户

方案 1 主要说明一下面向一个租户

从一个租户 (用户) 的角度来看,如果有多套不同的环境,那么这个时候可以根据指定的环境来创建不同的 namespce,以此来实现多环境的隔离。

例如,你可能有 dev,test 和 prod 三个不同的环境,那么使用一套 nacos 集群可以分别建以下三个不同的 namespace。如下图所示:

这里的单租户同样也适于小型项目,或者是项目不太多时的实施方案

通过定义不同的环境,不同环境的项目在不同的 Namespace 下进行管理,不同环境之间通过 Namespace 进行隔离

当多个项目同时使用该 Nacos 集群时,还可以通过 Group 进行 Namespace 内的细化分组

这里以 Namespace:dev 为例,在 Namespace 中通过不同 Group 进行同一环境中不同项目的 再分类

有了以上思路,我们通过代码来实践一下

Namespace 下新建配置文件

启动 Nacos-Server,进入 Nacos 控制台,切换到 Namespace:dev 界面,新建配置文件

  • DataId:nacos-namespace-one-dev.yml
  • Group:namespace-one
  • 配置格式:YAML
  • 配置内容:

    nacos: 
        config: 项目:nacos-namespace-one,Namespace:dev

继续新建配置文件

  • DataId:nacos-namespace-two-dev.yml
  • Group:namespace-two
  • 配置格式:YAML
  • 配置内容:

    nacos: 
        config: 项目:nacos-namespace-two,Namespace:dev

切换到 Namespace:test 环境,按照 dev 中的创建方式,分别创建 nacos-namespace-one-test.ymlnacos-namespace-two-test.yml

注意检查 DataId 是否正确、group、配置内容与环境是否匹配

创建项目

在聚合工程 Nacos 下创建名为 nacos-namespace-one 的子项目,该工程的依赖文件和启动类的代码与 Nacos(四)完全一致。

以下 NamespaceId 均来自创建 Namespace 时生成的 Id,在控制台命名空间页面中可以查看

创建 dev 环境配置文件bootstrap-dev.yml

server:
  port: 9911
spring:
  application:
    name: nacos-namespace-one
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: edbd013b-b178-44f7-8caa-e73071e49c4d
        group: namespace-one
      config:
        server-addr: 127.0.0.1:8848
        prefix: ${spring.application.name}
        file-extension: yml
        namespace: edbd013b-b178-44f7-8caa-e73071e49c4d
        group: namespace-one

创建 test 环境配置文件bootstrap-dev.yml

server:
  port: 9912

spring:
  application:
    name: nacos-namespace-one
  profiles:
    active: test
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        namespace: 0133bd1e-25c3-4985-96ed-a4e34efdea2e
        group: namespace-one
      config:
        server-addr: 127.0.0.1:8848
        prefix: ${spring.application.name}
        file-extension: yml
        namespace: 0133bd1e-25c3-4985-96ed-a4e34efdea2e
        group: namespace-one

重复以上操作,再创建一个名为 nacos-namespace-two 的子项目

nacos-namespace-two 项目的 dev 和 test 启动端口分别设置为 9921 和 9922,group 为:namespace-two

记得修改 spring.application.namenamespacegroup

启动工程

分别启动两个项目的两个环境(四个启动类), 如下图

现在我们有 2 个项目:nacos-namespace-onenacos-namespace-two

2 个项目分别有两个不同的环境 devtest

此时观察 Nacos-Server 控制台如下:

尝试访问接口来获取配置信息,验证是否可以读取相应环境配置

访问 127.0.0.1:9911/getValue, 返回:项目:nacos-namespace-one,Namespace:dev
访问 127.0.0.1:9912/getValue, 返回:项目:nacos-namespace-one,Namespace:test
访问 127.0.0.1:9921/getValue, 返回:项目:nacos-namespace-two,Namespace:dev
访问 127.0.0.1:9922/getValue, 返回:项目:nacos-namespace-two,Namespace:test

通过以上实验,方案 1 可以达到多环境多项目下的服务、配置管理的目标

方案 1 通过 Namespace 来隔离不同的环境(devtest), 在具体的环境 Namespace 中通过 Group 来管理不同的项目

Namespace 实施方案 2

了解了单租户的方案 1,再来看看 Nacos 推荐的面向多租户的方案 2

从多个租户 (用户) 的角度来看,每个租户 (用户) 可能会有自己的 namespace, 每个租户 (用户) 的配置数据以及注册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。

例如超级管理员分配了三个租户,分别为张三、李四和王五。张三负责 A 项目,李四负责 B 项目,王五负责 C 项目

分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名空间。如下图所示:

方案 2 通过 Namespace 来隔离多租户之间的服务和配置,但不仅于此,他有很好的扩展性

在该方案中,Group 同样也有用武之地。

需求改变下,公司发展迅速业务调整,张三负责 A 项目、B 项目、C 项目,李四负责 D 项目、E 项目、F 项目,王五负责 G 项目、H 项目、I 项目,

而每个项目又分了 dev、test、prod 三个环境,继续沿用之前的 Namespace 隔离租户方案,显得有些管理不便,这时候可以在 NameSpace 中加入 Group 进行项目环境分组,如图:

但是当业务规模更大的时候(不考虑 Nacos 集群能否支持的因素),张三、李四、王五每人都负责 10 多个项目时,即 项目数 > 环境数 时,可以通过 Group 进行项目分组,如下图:

通过上面的理论分析,可以看出方案二有很好的扩展性

依旧如上,我们通过代码来实践一下方案 2(Namespace 隔离租户 + group 环境分组)

场景描述

依旧使用上面的两个项目,假设现在有两个租户,张三、李四

张三负责项目:nacos-namespace-one, 李四负责项目:nacos-namespace-two,项目分别有 dev 和 test 环境

新建 Namespace 和配置文件

新建两个 Namespace 来隔离租户,分别为zhangsanlisi

在 Namespace:zhangsan 下创建配置文件

  • DataId:nacos-namespace-one-dev.yml
  • Group:namespace-one-dev
  • 配置格式:YAML
  • 配置内容:

    nacos: 
        config: 项目:nacos-namespace-one,Namespace:张三,环境:dev

继续创建 test 环境配置文件

  • DataId:nacos-namespace-one-test.yml
  • Group:namespace-one-test
  • 配置格式:YAML
  • 配置内容:

    nacos: 
        config: 项目:nacos-namespace-one,Namespace:张三,环境:test

参照以上操作,在 Namespace:lisi 命名空间中创建配置文件 nacos-namespace-two-dev.ymlnacos-namespace-two-test.yml

注意核对 DataId、Group、和配置内容

修改项目的配置文件 bootstrap.yml

修改项目 nacos-namespace-one 的 dev 配置文件bootstrap-dev.yml

server:
  port: 9911
spring:
  application:
    name: nacos-namespace-one
  profiles:
    active: dev
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
#        方案 2:NamespaceID\Group
        namespace: e0d75068-a12c-4314-9296-3f396139d5b3
        group: namespace-one-dev
      config:
        server-addr: 127.0.0.1:8848
        prefix: ${spring.application.name}
        file-extension: yml
#        方案 2:NamespaceID\Group
        namespace: e0d75068-a12c-4314-9296-3f396139d5b3
        group: namespace-one-dev

修改 test 配置文件bootstrap-test.yml

server:
  port: 9912
spring:
  application:
    name: nacos-namespace-one
  profiles:
    active: test
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
#        方案 2:NamespaceID\Group
        namespace: e0d75068-a12c-4314-9296-3f396139d5b3
        group: namespace-one-test
      config:
        server-addr: 127.0.0.1:8848
        prefix: ${spring.application.name}
        file-extension: yml
#        方案 2:NamespaceID\Group
        namespace: e0d75068-a12c-4314-9296-3f396139d5b3
        group: namespace-one-test

重复以上操作相应的修改项目 nacos-namespace-two 的 dev 和 test 配置文件

主要修改 namespace 和 group 属性,与命名空间 lisi 的 ID 和其下配置文件的 Group 对应

启动项目

分别启动两个项目的两个环境(四个启动类),启动成功如下图

此时两个项目分别启动两个环境后,注册到 Nacos 上不同的 Namespace 下,并读取相应环境的配置,具体如下:

nacos-namespace-one

  • dev: 注册到 Namespace:zhangsan,读取 Namespace:zhangsan 下 Group:namespace-one-dev 的配置
  • test: 注册到 Namespace:zhangsan,读取 Namespace:zhangsan 下 Group:namespace-one-test 的配置

nacos-namespace-two

  • dev: 注册到 Namespace:lisi,读取 Namespace:lisi 下 Group:namespace-two-dev 的配置
  • test: 注册到 Namespace:lisi,读取 Namespace:lisi 下 Group:namespace-two-test 的配置

此时 Nacos 控制台如下图:

ok 我们来测试下各个环境的服务能否访问到对应的配置

访问 127.0.0.1:9911/getValue, 返回:项目:nacos-namespace-one,Namespace:张三,环境:dev
访问 127.0.0.1:9912/getValue, 返回:项目:nacos-namespace-one,Namespace:张三,环境:test
访问 127.0.0.1:9921/getValue, 返回:项目:nacos-namespace-two,Namespace:李四,环境:dev
访问 127.0.0.1:9922/getValue, 返回:项目:nacos-namespace-two,Namespace:李四,环境:test

通过访问服务的接口,各个服务都可以准确的读取到各自环境下的配置文件

方案二可以看到同样支持服务和配置的隔离分组,同时支持业务的扩展,有较好的扩展性

问题描述

但是相信大家已经发现了一个问题,当使用的 Group 来进行分组后,配置文件相互之间可以实现不同环境与不同项目之间的分组隔离

但是服务注册后,虽然可以通过 Namespace 隔离,但指定的 Group 分组却并没有生效,依然是DEFAULT_GROUP

比如方案 1 所有项目启动后 Nacos 服务列表页如下图

这里本应该是我们自定义的分组 namespace-onenamespace-two却没有生效

由此发现,配置之间是达到了相互分组隔离名但 服务列表暂时并不支持

但是不要担心,Nacos 的社区极度活跃,社区的大佬们也发现了这一情况,并且在 Nacos-client 的源码中可以看到 NameingService 在加载配置文件时是有预留 Group 这一属性字段的。

所以既然 Nacos 提供了这一实践方案,正常使用只不过是时间问题。

总结

以上分析了 Nacos 对于 Namespace 提供的两种实践方案,同时进行了代码实验,均达到了预期的要求。

现对两种方案进行一个总结

  • 单租户方案(方案 1):适合小型项目,服务数量不多时,方案一完全够用
  • 多租户方案(方案 2):适合项目量多,有一定的团队规模,且服务数量较多时,可以相对条理清晰的管理和隔离配置及服务。

本文源码:https://github.com/larscheng/…

参考与感谢

Namespace 最佳实践


  • 文章作者: LarsCheng
  • 文章链接: 本文首发于个人博客:https://www.larscheng.com/nac…
  • 发布方式:OpenWrite 最懂你的科技自媒体管理平台
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LarsCheng’s Blog!

正文完
 0