13. Dubbo服务暴露 - 初始化
1. 开篇
本文主要介绍Dubbo服务的暴露过程的环境准备阶段。
服务导出简要流程如下:
- 读取配置信息生成
ServiceBean
- 服务注册根据配置信息将服务以及相关信息注册到注册中心
- 根据配置的协议不同,启动Netty或Tomcat
- Dubbo服务提供者启动监听动态配置修改
- 服务导出完成,发布导出完成事件
2. 启动类
Dubbo服务有一个很重要的启动类————DubboBootstrap
,这个启动类里有两个重要的属性:configManager
、environment
,这两个属性都和Dubbo的配置信息有关系。
2.1 启动类作用
DubboBootstrap
启动类主要功能如下:
- 初始化
configManager
和environment
对象。 - 注册
DubboShutdownHook
钩子,实现优雅停机。 - 更新配置中心
ConfigCenterBean
对象对应的值。 - 加载并更新远程配置。
- 检查
configManager
对象各个配置对象是否合法。 - 加载并初始化元数据中心。
- Dubbo服务导出。
2.2 ConfigManager
configManager
对象包含了Dubbo的各种Config配置,例如:ApplicationConfig
、MonitorConfig
、ModuleConfig
、ProtocolConfig
、RegistryConfig
、ProviderConfig
、ConsumerConfig
等。
这些配置对象都放在configsCache
属性里,如果有配置数据更新了,例如动态配置进行更新,那么会执行configManager.refreshAll()
方法进行刷新数据,因为configsCache
是一个普通的HashMap类型是数据不安全的,因此ConfigManager
类里引入了一个ReentrantReadWriteLock
进行读写控制。
ConfigManager
相当于一个本地缓存,这个类本身也提供了很多ADD/SET/GET
方法来添加、更新、获取configsCache
中对应的配置信息,下面为configsCache
内容示例。
2.3 Environment
environment
对象也是存放配置信息的,但是这个对象存放的是和系统相关的配置信息,例如:操作系统环境变量、Java虚拟机相关参数、用户自定义参数、动态配置中心参数等。
在Environment
类的构造方法中,会初始化几个参数如下:
PropertiesConfiguration
:存放配置文件相关配置信息,如dubbo.properties
。
SystemConfiguration
:存放操作系统相关的属性信息,通过System.getProperty
方法获取。
EnvironmentConfiguration
:存放Java虚拟机相关配置信息,通过System.getenv
方法获取。
InmemoryConfiguration
:存放内部的配置信息,分为应用配置和全局配置,如URL
的参数信息。
CompositeConfiguration
:存放配置中心的动态配置相关信息。
2.4 启动流程
Dubbo启动流程如下:
2.4.1 初始化initialize
该方法为Dubbo初始化配置、环境、元数据等,具体方法如下:
initFrameworkExts
,这个方法为通过Dubbo SPI
初始化 FrameworkExt
的实现类,其实现类有3个分别为:ConfigManager
、Environment
、ServiceRepository
,在initFrameworkExts
方法中主要是获取3个实现类的实例再分别调用其initialize
方法,不过只有Environment
重写了该方法。
2.4.2 开启配置中心startConfigCenter
先检查是否配置了配置中心相关的配置,如果没有配置的话,则使用注册中心RegistryConfig
的信息赋值给ConfigCenterConfig
。
从ConfigManager
对象里获取所有的ConfigCenterConfig
对象,循环遍历配置中心对象获取配置中心的配置信息,并且把这些配置信息设置到Environment
对象中,然后调用configManager.refreshAll()
方法刷新配置信息。可以看到,配置中心是可以有多个的。
2.4.3 加载远程配置loadRemoteConfigs
该方法主要功能为加载远程的注册中心配置和协议配置。
调用ConfigManager
的getRegistryIds
方法,getRegistryIds
方法会从Environment
对象的appExternalConfigurationMap
和externalConfigurationMap
中根据前缀dubbo.registries.
匹配,来获取所有注册相关的id值,再根据id值来查找或创建RegistryConfig
对象。ProtocolConfig
与RegistryConfig
基本一致。
2.4.4 检查全局配置checkGlobalConfigs
此方法主要是检查校验各个属性的配置是否合法,比如:name长度是否超长、是否包含非法字符等等,这里不再一一展开了。
2.4.5 开启元数据中心startMetadataCenter
此方法,先检查是否配置了元数据中心,如果没有配置的话,与配置中心一样会把注册中心的协议、端口、分组、鉴权等信息设置到元数据中心上。
获取ApplicationConfig
对象的metadataType
属性值,该值表示元数据类型,有两个值:remote
、local
分别表示为远程配置、本地配置,当metadataType
属性值为remote
时,必须配置元数据中心,否则会报错。
拿到元数据配置中心后,进行循环遍历,对其进行校验以及初始化操作。
对元数据配置中心初始化时,先通过Dubbo SPI
进行加载MetadataReportFactory
实现类实例,根据设置协议生成不同的对象,然后创建MetadataReport
对象,同时对元数据中心进行连接。
2.4.6 初始化元数据服务
private void initMetadataService() {
this.metadataService = getDefaultExtension();
this.metadataServiceExporter = new ConfigurableMetadataServiceExporter(metadataService);
}
initMetadataService
方法主要作用为初始化元数据服务,通过Dubbo SPI 加载WritableMetadataService
的实现类,WritableMetadataService
的默认实现类为InMemoryWritableMetadataService
,将加载完成的对象赋值给metadataService
。
初始化metadataServiceExporter
,将初始化好的metadataService
作为ConfigurableMetadataServiceExporter
的构造参数然后将这个类进行实例化并赋值给metadataServiceExporter
。
ConfigurableMetadataServiceExporter
这类的的作用是将MetadataService
接口实现类的对象,也就是WritableMetadataService
对象,以dubbo服务的形式暴露出去对外提供服务,这样带来的好处是,我们可以使用dubbo协议访问MetadataService
接口里面的方法。
3. 后记
本文主要介绍Dubbo服务的暴露过程的环境准备阶段,本阶段看着很简单,但是过程很繁琐,书写起来也比较麻烦,欢迎吐槽~