该文章内容发布已经超过一年,请注意检查文章中内容是否过时。
关于元数据中心的概念对于大部分用户来说是比较陌生的,配置中心的话我们还好理解,对于元数据中心是什么,我们来看下我从官网拷贝过来的一段文字:
元数据中心在2.7.x版本开始支持,随着应用级别的服务注册和服务发现在Dubbo中落地,元数据中心也变的越来越重要。在以下几种情况下会需要部署元数据中心:
元数据中心并不依赖于注册中心和配置中心,用户可以自由选择是否集成和部署元数据中心,如下图所示:
该图中不配备配置中心,意味着可以不需要全局管理配置的能力。该图中不配备注册中心,意味着可能采用了Dubbo mesh的方案,也可能不需要进行服务注册,仅仅接收直连模式的服务调用。 官网参考文章地址:
综上所述可以用几句话概括下:
元数据中心的启动是在DefaultApplicationDeployer中的初始化方法 initialize() 中:如下所示
这里只看下 startMetadataCenter();方法即可
关于元数据中心我们看下 startMetadataCenter()方法来大致了解下整个流程
前面在说配置中心的时候有说过配置中心如果未配置会使用注册中心的地址等信息作为默认配置,这里元数据做了类似的操作:如代码: DefaultApplicationDeployer类型的 useRegistryAsMetadataCenterIfNecessary()方法
这个代码有些细节就不细说了 我们概括下顺序梳理下思路:
元数据的配置可以参考官网:元数据参考手册
这里主要看下可配置项有哪些 对应类型为MetadataReportConfig 在官网暂时未找到合适的文档,这里整理下属性列表方便后续配置说明查看:
配置变量 | 类型 | 说明 |
---|---|---|
id | String | 配置id |
protocol | String | 元数据协议 |
address | String | 元数据中心地址 |
port | Integer | 元数据中心端口 |
username | String | 元数据中心认证用户名 |
password | String | 元数据中心认证密码 |
timeout | Integer | 元数据中心的请求超时(毫秒) |
group | String | 该组将元数据保存在中。它与注册表相同 |
parameters | Map<String, String> | 自定义参数 |
retryTimes | Integer | 重试次数 |
retryPeriod | Integer | 重试间隔 |
cycleReport | Boolean | 默认情况下, 是否每天重复存储完整的元数据 |
syncReport | Boolean | Sync or Async report. |
cluster | Boolean | 需要群集支持,默认为false |
registry | String | 注册表配置id |
file | String | 元数据报告文件存储位置 |
check | Boolean | 连接到元数据中心时要应用的失败策略 |
主要看这一行比较重要的逻辑:
在了解这一行逻辑之前我们先来看下元数据相关联的类型:
MetadataReportInstance中的初始化方法init
关于元数据的初始化我们主要看两个位置:
关于元数据工厂类型MetadataReportFactory,元数据工厂 用于创建与管理元数据对象, 相关类型如下:
我们这里主要以为Zookeeper扩展的元数据工厂ZookeeperMetadataReportFactory类型为例子: 实现类型逻辑不复杂,这里就直接贴代码看看:
元数据工厂的实现比较简单
如果我们想要实现一个元数据工厂扩展可以参考Zookeeper的这个方式
前面的从元数据工厂中获取元数据操作对象的逻辑处理代码如下:
关于元数据对象,用于元数据信息的增删改查等逻辑的操作与元数据信息的缓存
我们这里还是以Zookeeper的实现ZookeeperMetadataReportFactory类型做为参考:
我们先来看这个逻辑
ZookeeperMetadataReportFactory的父类型AbstractMetadataReportFactory中的getMetadataReport方法如下:
上面这个抽象类AbstractMetadataReportFactory中的获取元数据操作对象的模版方法getMetadataReport(URL url), 用了双重校验锁的逻辑来创建对象缓存对象,又用了模版方法设计模式,来让抽象类做通用的逻辑,让实现类型去做扩展, 虽然代码写的太长了些整体还是用了不少的设计思想.
我们直接看这个代码:
这个创建元数据操作对象的代码实际上走的是实现类型的逻辑:
来自工厂Bean ZookeeperMetadataReportFactory的工厂方法如下所示:
创建了元数据操作对象,这里我们继续看下元数据操作对象ZookeeperMetadataReport创建做了哪些逻辑: 来自ZookeeperMetadataReport的构造器:
核心的公共的操作逻辑封装在父类AbstractMetadataReport里面 我们来看前面super调用的构造器逻辑: 如下所示:
这里来总结下元数据操作的初始化逻辑:
关于元数据同步可以看AbstractMetadataReport类型的publishAll方法:
这里有个方法叫做calculateStartTime 这个代码是随机时间的between 2:00 am to 6:00 am, the time is random. 2点到6点之间启动, 低峰期启动自动同步 返回值:
AbstractMetadataReport类型的
AbstractMetadataReport类型的doHandleMetadataCollection
提供端元数据的存储: AbstractMetadataReport类型的storeProviderMetadata
AbstractMetadataReport类型的storeProviderMetadataTask 具体同步代码:storeProviderMetadataTask
上面代码我们主要看本地内存中的元数据同步到元数据中心和存本地的两个点:
//内存中的元数据同步到元数据中心
这个方法会调用当前子类重写的具体存储逻辑:这里我们以 ZookeeperMetadataReport的doStoreProviderMetadata举例:
这里参数我们举个例子: 提供者的元数据内容如下: 节点路径为:
格式:
具体的元数据内容如下: 比较详细的记录了应用信息,服务接口信息和服务接口对应的方法信息
本地缓存文件的写入 可以看下如下代码 AbstractMetadataReport类型的saveProperties方法
主要看如下代码:
SaveProperties类型代码如下:
继续看doSaveProperties方法:
写入文件的内容大致如下