美文网首页
dubbo之export浅析

dubbo之export浅析

作者: 我是你的小眼睛儿 | 来源:发表于2018-01-04 17:13 被阅读0次

设计

整体设计图(引用自官网)

以ServiceConfig类为起点,主要过程为执行invoker和Exporter两个操作,这样看起来就清晰了。下面是整个export的时序图,从中可以看出ServiceConfig动作为createInvoker()和export(),Protocol执行了init()和exported()。

时序图(引用自官网)

注册中心暴露服务

ServiceConfig 解析出的 URL 的格式为: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode("dubbo://service-host/com.foo.FooService?version=1.0.0")

基于扩展点自适应机制,通过 URL 的 registry:// 协议头识别,就会调用 RegistryProtocolexport() 方法,将 export 参数中的提供者 URL,先注册到注册中心。

再重新传给 Protocol 扩展点进行暴露: dubbo://service-host/com.foo.FooService?version=1.0.0,然后基于扩展点自适应机制,通过提供者 URL 的 dubbo:// 协议头识别,就会调用 DubboProtocolexport() 方法,打开服务端口。

暴露服务主过程

首先 ServiceConfig 类拿到对外提供服务的实际类 ref(如:HelloWorldImpl),然后通过 ProxyFactory 类的 getInvoker 方法使用 ref 生成一个 AbstractProxyInvoker 实例,到这一步就完成具体服务到 Invoker 的转化。接下来就是 Invoker 转换到 Exporter 的过程。

Dubbo 处理服务暴露的关键就在 Invoker 转换到 Exporter 的过程,上图中的红色部分。 Dubbo 和 RMI 这两种典型协议的实现如下:

  • Dubbo 的实现
    Dubbo 协议的 Invoker 转为 Exporter 发生在 DubboProtocol 类的 export 方法,它主要是打开 socket 侦听服务,并接收客户端发来的各种请求,通讯细节由 Dubbo 自己实现。

  • RMI 的实现
    RMI 协议的 Invoker 转为 Exporter 发生在 RmiProtocol类的 export 方法,它通过 Spring 或 Dubbo 或 JDK 来实现 RMI 服务,通讯细节这一块由 JDK 底层来实现,这就省了不少工作量。

暴露过程

初始化的时候扫描配置文件,调用父类的方法registerBeanDefinitionParser(),存入一个名为parsers的hashMap中。

image.png

然后ServiceConfig类中的export方法不知道怎么的就执行了到这了,可以看到方法里可以立即加载和延时加载。

image.png

在调用当前类的doExport方法。方法中检查了加载的参数完不完整,正不正确。

img

接下来进入doExportUrls();方法,可以看到这里有个for循环,可以接受多个注册地址。

image.png

然后进入doExportUrlsFor1Protocol()方法,这个方法比较长,前半段负责检查拼装参数,还有一些逻辑,我觉得最重要的是下面箭头所指的两行代码,第一个是通过代理工厂生成代理方法,第二个是暴露服务。

image.png

第二个会进入ProtocolFilterWrapper的export方法,调用buildInvokerChain链

image.png

会默认进入DubboProtocol里,在这里的调用openServer()

image.png

仔细看看openServer()都干了啥,openServer调用createServer(url),createServer(url)中最重要的bind方法。

image.png

一步一步走下去,看到是调用了Transporters的bind方法。

image.png

点进去bind方法,可以看到getTransporter()这个方法返回了一个Transporter对象,看一下Transporter的接口,bind方法上有@Adaptive注解,在 Dubbo 的 ExtensionLoader 的扩展点类对应的 Adaptive 实现是在加载扩展点里动态生成。指定提取的 URL 的 Key 通过 @Adaptive 注解在接口方法上提供。对于 bind() 方法,Adaptive 实现先查找 server key,如果该 Key 没有值则找 transport key 值,来决定代理到哪个实际扩展点。默认使用SPI中设定的值,所以是netty。

image.png
transporter
Adaptive

在NettyServer继承了AbstractServer并且实现了Server接口,可以看到NettyServer在构造方法中实现了父类的构造方法,调用了doOpen,也可以看到打出start bind export的日志。

image.png
image.png
image.png

然后进入到RegistryProtocol的export方法,在这里注册服务到zookeeper


image.png

调用下面方法,设置协议等

image.png

执行这句 final Registry registry = getRegistry(originInvoker);


image.png

调用AbstractRegistryFactory的getRegistry

image.png

ZookeeperRegistryFactory的createRegistry的方法,因为ZookeeperRegistryFactory继承了AbstractRegistryFactory,AbstractRegistryFactory实现了RegistryFactory接口,而这个接口的getRegistry方法注解为@Adaptive({"protocol"}),之前有设置协议为zookeeper,所以根据名称选择了ZookeeperRegistryFactory的实现。

image.png

这里调用zookeeperTransporter的connect,就跟调用netty一样的


image.png

默认Zkclient的实现


image.png
在这里创建连接
image.png

创建成功之后,dubbo自己存一份


image.png

然后返回RegistryProtocol的export方法,添加一些订阅监听
最后回到ServiceConfig的export方法,整个服务暴露完成。


参考:http://dubbo.io/books/dubbo-dev-book/design.html
各位大神多多指导

相关文章

网友评论

      本文标题:dubbo之export浅析

      本文链接:https://www.haomeiwen.com/subject/eptrnxtx.html