Dubbo 服务暴露
1. 服务暴露时序图
2. 源码分析
DubboBootstrap.exportServices
从配置管理器中获取到所有的ServiceConfig实例,遍历,然后一个一个的暴露。
ServiceConfig.export
- 如果DubboBootstrap为空,也就没有初始化,就初始化一下DubboBootstrap
- init serviceMetadata 初始化服务的原数据信息
- export服务,判断是否延时export
- 发布ServiceConfigExportedEvent事件
ServiceConfig.doExportUrls
一个服务ServiceConfig可能同时以多个协议export。
- 获取服务注册中心的URL地址信息,一个服务可以同事在多个注册中心注册
- 遍历服务要暴露的协议集合。一个服务可能同时以dubbo协议,rest协议等export。一般默认是dubbo协议,也推荐是用dubbo协议
ServiceConfig.doExportUrlsFor1Protocol
- 设置协议名称,默认为dubbo
- 设置各个参数,包括side、metadata-type、provider等等
- 填充方法级别的各个参数,即dubbo:method 中的各个参数
- 设置是否generic
- 设置token ServiceConfig token
- 初始化 serviceMetadata attachments
- 生成对应service的url,填充host、port参数
- 如果自定义ConfiguratorFactory,则获取自定义的参数
- 获取scope参数,非remote,则执行exportLocal
- 如果scope不是local,registryURLs不为空,则根据对应的registryURLs,循环生成url,invoker,wrapperInvoker对象,最终执行PROTOCOL#export(wrapperInvoker),完成暴露
- 如果scope不是local,且registryURLs为空,则生成invoker,wrapperInvoker执行执行PROTOCOL#export(wrapperInvoker),完成。
通过以上流程,我们可以看到核心的暴露方法为exportLocal和PROTOCOL.export两个方法。
- scope = none,不导出服务
- scope != remote,导出到本地
- scope != local,导出到远程
ProxyFactory.getInvoker
Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
不管是导出到本地,还是远程。进行服务导出之前,均需要先创建 Invoker,这是一个很重要的步骤。因此下面先来分析 Invoker 的创建过程。
Invoker 是由 ProxyFactory 创建而来,Dubbo 默认的 ProxyFactory 实现类是 JavassistProxyFactory。
ServiceConfig.exportLocal
exportLocal 方法比较简单,首先根据 URL 协议头决定是否导出服务。若需导出,则创建一个新的 URL 并将协议头、主机名以及端口设置成新的值。然后创建 Invoker,并调用 InjvmProtocol 的 export 方法导出服务。
RegistryProtocol.exportRemote
与导出服务到本地相比,导出服务到远程的过程要复杂不少,其包含了服务导出与服务注册两个过程。这两个过程涉及到了大量的调用,比较复杂。
- 调用 doLocalExport 导出服务
- 向注册中心注册服务
- 向注册中心进行订阅 override 数据
- 创建并返回 DestroyableExporter
DubboProtocol.export
假设运行时协议为 dubbo,此处的 protocol 变量会在运行时加载 DubboProtocol,并调用 DubboProtocol 的 export 方法。
openServer
服务注册
服务注册主要在 RegistryProtocol.export.
3. 总结
本篇文章详细分析了 Dubbo 服务导出过程,包括配置检测,URL 组装,Invoker 创建过程、导出服务以及注册服务等等。
4. 鸣谢
服务导出