Dubbo源码|十三、Dubbo服务暴露—初始化

1,516 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第17天,点击查看活动详情

开篇

本文主要介绍Dubbo服务的暴露过程的环境准备阶段。

服务导出简要流程如下:

  1. 读取配置信息生成ServiceBean
  2. 服务注册根据配置信息将服务以及相关信息注册到注册中心
  3. 根据配置的协议不同,启动Netty或Tomcat
  4. Dubbo服务提供者启动监听动态配置修改
  5. 服务导出完成,发布导出完成事件

启动类

Dubbo服务有一个很重要的启动类————DubboBootstrap,这个启动类里有两个重要的属性:configManagerenvironment,这两个属性都和Dubbo的配置信息有关系。

启动类作用

DubboBootstrap启动类主要功能如下:

  1. 初始化configManagerenvironment对象。
  2. 注册DubboShutdownHook钩子,实现优雅停机。
  3. 更新配置中心ConfigCenterBean对象对应的值。
  4. 加载并更新远程配置。
  5. 检查configManager对象各个配置对象是否合法。
  6. 加载并初始化元数据中心。
  7. Dubbo服务导出。

ConfigManager

configManager对象包含了Dubbo的各种Config配置,例如:ApplicationConfigMonitorConfigModuleConfigProtocolConfigRegistryConfigProviderConfigConsumerConfig等。

这些配置对象都放在configsCache属性里,如果有配置数据更新了,例如动态配置进行更新,那么会执行configManager.refreshAll()方法进行刷新数据,因为configsCache是一个普通的HashMap类型是数据不安全的,因此ConfigManager类里引入了一个ReentrantReadWriteLock进行读写控制。

ConfigManager相当于一个本地缓存,这个类本身也提供了很多ADD/SET/GET方法来添加、更新、获取configsCache中对应的配置信息,下面为configsCache内容示例。

image.png

Environment

environment对象也是存放配置信息的,但是这个对象存放的是和系统相关的配置信息,例如:操作系统环境变量、Java虚拟机相关参数、用户自定义参数、动态配置中心参数等。

Environment类的构造方法中,会初始化几个参数如下: image.png

PropertiesConfiguration:存放配置文件相关配置信息,如dubbo.properties

SystemConfiguration:存放操作系统相关的属性信息,通过System.getProperty方法获取。

EnvironmentConfiguration:存放Java虚拟机相关配置信息,通过System.getenv方法获取。

InmemoryConfiguration:存放内部的配置信息,分为应用配置和全局配置,如URL的参数信息。

CompositeConfiguration:存放配置中心的动态配置相关信息。

启动流程

Dubbo启动流程如下: image.png

初始化initialize

该方法为Dubbo初始化配置、环境、元数据等,具体方法如下:

image.png

initFrameworkExts,这个方法为通过Dubbo SPI 初始化 FrameworkExt的实现类,其实现类有3个分别为:ConfigManagerEnvironmentServiceRepository,在initFrameworkExts方法中主要是获取3个实现类的实例再分别调用其initialize方法,不过只有Environment重写了该方法。

开启配置中心startConfigCenter

image.png

先检查是否配置了配置中心相关的配置,如果没有配置的话,则使用注册中心RegistryConfig的信息赋值给ConfigCenterConfig

ConfigManager对象里获取所有的ConfigCenterConfig对象,循环遍历配置中心对象获取配置中心的配置信息,并且把这些配置信息设置到Environment对象中,然后调用configManager.refreshAll()方法刷新配置信息。可以看到,配置中心是可以有多个的。

加载远程配置loadRemoteConfigs

image.png

该方法主要功能为加载远程的注册中心配置和协议配置。

调用ConfigManagergetRegistryIds方法,getRegistryIds方法会从Environment对象的appExternalConfigurationMapexternalConfigurationMap中根据前缀dubbo.registries.匹配,来获取所有注册相关的id值,再根据id值来查找或创建RegistryConfig对象。ProtocolConfigRegistryConfig基本一致。

检查全局配置checkGlobalConfigs

此方法主要是检查校验各个属性的配置是否合法,比如:name长度是否超长、是否包含非法字符等等,这里不再一一展开了。

开启元数据中心startMetadataCenter

image.png

此方法,先检查是否配置了元数据中心,如果没有配置的话,与配置中心一样会把注册中心的协议、端口、分组、鉴权等信息设置到元数据中心上。

获取ApplicationConfig对象的metadataType属性值,该值表示元数据类型,有两个值:remotelocal分别表示为远程配置、本地配置,当metadataType属性值为remote时,必须配置元数据中心,否则会报错。

拿到元数据配置中心后,进行循环遍历,对其进行校验以及初始化操作。

对元数据配置中心初始化时,先通过Dubbo SPI 进行加载MetadataReportFactory实现类实例,根据设置协议生成不同的对象,然后创建MetadataReport对象,同时对元数据中心进行连接。

初始化元数据服务
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接口里面的方法。

后记

本文主要介绍Dubbo服务的暴露过程的环境准备阶段,本阶段看着很简单,但是过程很繁琐,书写起来也比较麻烦,欢迎吐槽~