闲文 : Nacos Server 的配置管理

602 阅读4分钟

首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…

一 .前言

Nacos 图形界面的第一个就是配置管理 ,这一篇来深入了解一下 , 如何做一套配置的管理.

二 .配置的存储方式

nacos 的配置处理主要在 ConfigServletInner 中 , 整体核心逻辑如下 :

2.1 Server 中配置的加载

默认情况下 , Nacos 配置是存储在 Apache Derby 中的 ,但是使用者可以通过 extend 扩展更多的Datasource 处理方式 .

增删改查很基础 , Nacos 的配置处理都在 ConfigController 中 , 严格按照 Restful 标准来实现的 , 就不深入看了 . 只关注里面值得我们学习的地方 :

启动时配置加载

启动时主要会将配置信息加载到一个 ConcurrentHashMap 中 , 用于后续的锁判断和读取 , 最终都会通过 DumpService 调用 ConfigCacheService 来完成配置的缓存 .

而对于 Mysql 等 extends 的方式 , 会通过 ExternalDumpService 触发外部配置初始化

等缓存后 , 就会放入 ConcurrentHashMap , 在读取配置时使用

Apache Derby 是什么 , 如何进行扩展 ?

Apache Derby是一个完全用java编写的数据库 , 它可以内嵌到应用程序中使用. Derby 作为默认库在 LocalDataSourceServiceImpl 中加载 :


// M1 : 当触发 Database 操作的时候 , 最终会调用 StandaloneDatabaseOperateImpl
-  DynamicDataSource.getInstance().getDataSource() : 首先获取对应的 DataSourceService

// M2 : DynamicDataSource 中选择对应的 DataSource , 主要支持2种方式
- ExternalDataSourceServiceImpl : 其他自定义
- LocalDataSourceServiceImpl : 默认数据源配置方式


// M3 : LocalDataSource 初始化连接
final String jdbcUrl = "jdbc:derby:C:\nacos\data\derby-data;create=true";


// M4 : initialize
- HikariDataSource ds = poolProperties.getDataSource() : 获取连接池配置
- execute(ds.getConnection(), "META-INF/schema.sql") : 执行初始化 SQL 

2.2 Server 中配置的查询

> C- ConfigServletInner # doGetConfig : 

// 核心 : 从 中获取配置
configInfoBase = persistService.findConfigInfo(dataId, group, tenant);
- 从这里实际上可以看出来 , Config 配置实际上是会持久化的 ,而且 Nacos 持久化配置的方式很多 
- Nacos 默认使用  Apache Derby 作为数据存储

2.3 扩展

Nacos 还支持哪些数据库 ?

从 DataSourceService 的角度看 , 实际上是有2个实现类 , 其中 ExternalDataSourceServiceImpl 主要是为了用于扩展功能 , 以 Mysql 为例 :

spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos001?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=123456
// PS : Nacos 数据库文件在 META-INF/schema.sql 中


M1- ExternalDataSourceServiceImpl # init : 其中主要通过 个对象来实现整个数据源的管理
    1- List<HikariDataSource> 用来管理整个数据源集合
    2- List<JdbcTemplate> testJtList 用来做监控检查集群
    3- List<Boolean> isHealthList 用于判断节点是否监控
    4- DataSourceTransactionManager + TransactionTemplate 做事务管理
M2- ExternalDataSourceServiceImpl # reload : 此环节实际加载数据源
    1- List<HikariDataSource> dataSources = new ArrayList<>() 用来存储
    2- for 循环 environment.db 配置 
    3- HikariDataSource 通过 DataSourcePoolProperties 构建

// PS : 从上面的配置其实就已经看出来了 , 有 db.0\1\2\3 这类配置

三 . 细节点

3.1 整体流程图

image.png

3.2 实现业务控制配置

TODO : 意义不大

四 . 配置的读取

4.1 Client 请求

Client 请求之前我们分析过 @ juejin.cn/post/701818… , 最终会通过 Rest 接口完成配置的调用 :

// C- ClientWorker # getServerConfig
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);

// 请求参数
{"dataId":"nacos-config","group":"DEFAULT_GROUP"}

// 返回结果
RestResult{code=200, message='null', data=gang.test.name=gang}

补充 : 命名空间的使用方式

命名空间是 Nacos 中一个很重要的概念 ,可以用来区分不同的业务应用群. 命名空间主要体现在 agent 请求中 :

image.png

在传递过程中会被转义为 tenant 进行传递.

4.2 Server 返回

ConfigController 相对于日常业务开发的接口来说 , 是有一点复杂的. 通过 RequestMethod , RequestParam 多个角度判断具体的执行方法

这里参数看一下就知道了 , 主要来了解 namespace 的处理方式

// 通过 tenant 实现空间隔离
final String groupKey = GroupKey2.getKey(dataId, group, tenant);

五. 思考

Nacos 会将数据以数据库的方式进行持久化 , 我们可以对其进行扩展和处理. 同时由于其使用了 HikariDataSource 连接池 , 所以也可以对其进行高并发的控制.

日常中 ,我们主要是通过 console 对配置进行处理 , Nacos 不论是 Client 还是 console , 都是通过 API 发起的调用 , 实际上我们做好了 AccessToken 集成后 , 是可以实现应用端对配置的增删改查 . 所以把 Nacos 作为一个业务级的配置中心也是可行的.

但是其中配置的管理并没有看到分布式配置锁的控制 , 所以这一块可能还是需要进行改造.

在配置中虽然存在 namespacegroup 2个分组维度 ,但是最终都是通过 groupKey 进行的数据查询 , 这一点和我预想的命名空间有点不一样 , 主要是由于 K8S 中 命名空间的影响过于深刻.

东西比较简单 , 仅仅也只是好奇对这一块抽空看了一下 ,做一些输出以便于后续的学习.

总结

这篇文章不复杂 , 主要是为了看自动刷新看的前置知识点 , 并且试图从其中学习到一点什么.