17

Dubbo之服务暴露

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzUzODk0NDE2Nw%3D%3D&%3Bmid=2247483765&%3Bidx=1&%3Bsn=961cc3761ae15c21681078051e6dcdf3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

RzyaquE.png!web

前言

本文 Dubbo 使用版本 2.7.5

Dubbo 通过使用 dubbo:service 配置或 @service 在解析完配置后进行服务暴露,供服务消费者消费。

Dubbo 的服务暴露有两种:

  • 远程暴露

  • 本地暴露

可以通过 scope 显式指定暴露方式:

  • none 不暴露

  • remote 远程暴露

  • local 本地暴露

服务暴露流程

下面是一个服务暴露的流程图:

zM3ye2J.jpg!web

ProxyFactory是动态代理,用来创建 Invoker 对象,实现代理使用 JavassistProxyFactoryJdkProxyFactory

Invoker是一个服务对象实例,Dubbo 框架的实体域。它可以是一个本地的实现,一个远程的实现或一个集群的实现,可以向它发起 Invoker 调用。

Protocol是服务域,负责 Invoker 的生命周期管理,是 Invoker 暴露和引用的主要功能入口,对应该类的 exportrefer 方法。

Exporter是根据不同协议暴露 Invoker 进行封装的类,它会根据不同的协议头进行识别(比如: registry://dubbo:// ),调用对应 XXXProtocolexport() 方法。

从上图中可以看到,Dubbo 中服务暴露分为两个大步骤:第一步通过代理将服务实例转换成 Invoker,这就是通过我们常用的反射实现。第二步将 Invoker 根据具体的协议转换成 Exporter,这是就是我们要分析的核心。从这里可以看到 Dubbo 服务对象都是围绕 Invoker 进行工作。

远程暴露

服务远程暴露从字面上理解,就是将服务跨网络进行远程通信,并非同一 JVM 中的服务进行调用。服务最后都是转换成 org.apache.dubbo.config.spring.ServiceBean ,它的UML类图:

fqANNbV.png!web

ServiceBean 继承自 ServiceConfig ,服务在 ServiceConfig#doExportUrls 根据不同协议进行暴露。

neIZrmE.jpg!web

通过获取所有注册中心实例(registryURLs)后,进行依次暴露,暴露操作在 doExportUrlsFor1Protocol 中。

上面是代码片段为暴露服务的核心,可以看到 scope 由三个值控制是否暴露和远程或本地暴露,默认远程和本地都暴露。在远程调用中,分为 使用注册中心暴露直接暴露 (默认dubbo协议),它们之间的区别在url上:

  • 无注册中心:dubbo://192.168.3.19:20880/xxxx

  • 有注册中心: registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=provider&dubbo=2.0.2&export= dubbo://192.168.3.19:20880/xxxx

无注册中心的直接暴露服务。有注册中心的先创建注册中心,再得到 export 的服务地址,然后暴露服务,当服务暴露成功后把服务元数据注册到注册中心。

代码中 protocol#export 会根据服务 url 的请求头进行区分不同 XXXProtocol#export 的逻辑,比如。目前 Dubbo 中有以下几种:

FfeEJvM.jpg!web

本地暴露

同一个应用中,可能既要提供服务远程暴露给其他应用引用,也要给自身提供引用。如果只提供远程暴露的话,当自身应用需要引用自身的服务时,需要通过远程通信访问,那么这大大浪费网络资源。这是就需要用 injvm 协议暴露,就是我们所说的本地暴露,无需跨网络远程通信,可以更好的节省资源。通过上面代码中,我们知道本地暴露调用的是 ServiceConfig#exportLocal 方法。

zIvyYvv.png!web

本地暴露会指定 injvm 协议,并且 host 指定为本地 127.0.0.1 和端口号为0。protocol.export 调用 InjvmProtocol#export 实现:

export 中返回了 InjvmExporter 实例化对象。

本地暴露就比较简单,将 Invoker 直接保存在 InjvmExporter 的 exporterMap 中。

最后

本篇对 Dubbo 的服务暴露流程进行了分析,核心点就是开篇图中的得到 Invoker 后转化到 Export。其中更多详细的地方,由于展开后篇幅太大,不能一一写到,会在今后相关的 Dubbo 文章再进行讲解。

关注【ytao】,更多原创好文

YRNbMrQ.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK