文档章节

Dubbo源码分析-Remoting层

robin-yao
 robin-yao
发布于 2016/12/11 21:56
字数 1795
阅读 671
收藏 33

Dubbo Github地址 https://github.com/alibaba/dubbo.git

Dubbo Remoting 模块是dubbo底层通信模块的实现。实现对请求/应答的各种逻辑处理,包括同步,异步,心跳等逻辑,最底层的通信借助netty或者mina实现,还有通过jetty servlet暴漏http服务的实现方式。

Remoting Api

公共基础接口类

  • Endpoint

Endpoint 字面意思是端点,端点接口的基本操作有获取端点对应的URL,LocalAddress,及发送关闭Channel的操作;

  • Channel

Channel接口继承Endpoint ,多了对Attribute的操作接口(get,set,remove)及获取连接状态接口,多了获取远端的操作getRemoteAddress方法;

  • ChannelHandler

ChannelHandler 主要包含对Channel的一些处理:
connected(Channel channel);
disconnected(Channel channel);
sent(Channel channel, Object message);
received(Channel channel, Object message);

  • Client

Client继承了Endpoint, Channel, Resetable,并添加reconnect接口

  • Server

Server除了继承Endpoint,还多了下面两个接口:
Collection<Channel> getChannels() 获取所有的Channel;
Channel getChannel(InetSocketAddress remoteAddress) 根据地址获取特定Channel;

  • Codec

encode,decode 编码解码消息

  • Transporter

Server bind(URL url, ChannelHandler handler) 监听服务端
Client connect(URL url, ChannelHandler handler) 连接到服务端 Transporter 实现类根据采用的底层通信框架的不同,具体封装不同的实现比如netty如图:
输入图片说明

输入图片说明
总结一下这几个基础接口的关系,从Endpoint,Channel,Client,Server的继承关系可以看出,Endpoint作为基础接口包含一些获取端点地址,获取channelHandler,发送消息的接口;
Channel继承Endpoint,Channel可以理解成现实的生活中的水管,它有端点的属性,同时它又有本身的属性;
Client本身是个端点,同时它又可以借助Channel对Server进行连接,它只能对属于它的那个Channel进行操作;
Server本身也是个端点,但它没有继承Channel,因为它是要对多个Channel进行有选择的操作,所以它才有上门列举的那两个操作; Transporter接口明显功能是发起客户端连接或者服务端监听的作用,Transporters的作用主要是通过dubbo采用的SPI思想去根据配置加载Transporter具体实现类,去完成相应的动作;
这里涉及的Client Server Channel都是上层通用对象的抽象,预定义通用属性方法,底层可以灵活的借用不同的框架去实现。大家不要把这些概念和netty mina里的概念混淆。

Buffer包

该包下的类主要是对字节码的操作的封装,ChannelBuffer定义了相应的操作接口,它的实现有Heap实现,和堆外直接内存两张实现;ChannelBuffers实现了对ChannelBuffer操作工具;大概类图如下:
输入图片说明

Transport包

输入图片说明
这里主要是对Client接口的部分实现,AbstractClient实现了Client大部分功能,仅把具体的通信操作留给所依赖的底层通信框架来实现。它实现了连接时锁控制逻辑,重试机制,及加载所要采用的线程池等逻辑。 AbstractServer 里面的逻辑想对简单,仅仅是对一些属性做了些准备,比如从url中解析所要监听的地址,获取线程池,还实现了一个对所有客户端发送消息的send方法。

输入图片说明
上面类图主要展示ChannelHandler的相关实现,ChannelHandler主要是触发Channel进行 CONNECTED,DISCONNECTED,SENT,RECEIVED,CAUGHT这个五个操作,其中WrappedChannelHandler对ChannelHandler做了包装,采用了装饰者模式,直接调用构造函数传入的handler来触发相关操作。这里的Handler设计巧妙,handler里嵌handler,每个handler只需做自己的特殊处理然后交给下一个handler即可,形成了一个处理链,实现功能的分层实现。这里会产生一个疑问,大家这些ChannelHandler都在做自己的业务逻辑处理然后调用handler.xxx(channel),好像谁也没有去触发channel上的动作,这个是在client去做的,其实client本身实现了ChannelHandler接口,比如NettyClient。 上图中的AllChannelHandler ,ExecutionChannelHandler,MessageOnlyChannelHandler,ConnectionOrderedChannelHandler 都是起到分发执行handler动作的类,他们都放在dispatcher包下面,只不过有的是在线程池里去异步执行的具体的handler对channel的操作,有的是直接在本线程中直接执行。

Exchange包

输入图片说明
Exchange这个包下的类主要是提供了可发起远程请求的ExchangeClient,和监听服务端的ExchangeServer。其具体实现分别是HeaderExchangeClient和HeaderExchangeServer。 Exchangers 调用 HeaderExchanger去实现客户端connect,服务端bind动作,分别生成HeaderExchangeClient与HeaderExchangeServer。 输入图片说明

这里Transporters会根据配置的具体Transporter实现类(NettyTransporter,MinaTransporter)来实例化具体的Client,或Server。

输入图片说明

Exchange包层主要是ExchangeClient ExchangerServer ,他们在Transport层上加入了心跳检测,也加入了异步处理逻辑的实现ResponseFuture。其中ResponseFuture 的实现类DefaultFuture,主要是借助ReentrantLock和Condition实现,大家可以看下源码。

Telnet包

输入图片说明
该包下的类主要是实现了一些handler,通过telnet命令行查询状态,log等信息。

Remoting Netty

上面的逻辑把remoting层的功能大概实现了,唯独把依赖底层通信框架的部分抽象给具体的框架实现。Dubbo底层实现有Mina,Netty,Grizzly,还有借助jetty把服务暴漏成http的方式。这里我们只简单的介绍下借助Netty的实现。 这里分别介绍下NettyChannel, NettyClient, NettyServer, NettyHandler, NettyTransporter。

NettyChannel除了继承dubbo本身定义的Channel接口逻辑,这里它把Netty中的Channel概念作为构造参数传入,因为所有的交互最终还是依赖netty中的channel去做。

NettyHandler这里是实现扩展了SimpleChannelHandler,同时把dubbo中定义的handler作为构造参数传入,当触发了netty中的读 写 连接断开等事件时,就会执行各种handler里定义的逻辑。

NettyClient 这里的逻辑比较简单,就是实现AbstractClient中留下的各种doXXX抽象方法,发起远程连接。

NettyServer 通过Netty bootstrap开启服务端监听。

这里把dubbo remoting层涉及到的概念和逻辑基本介绍了。那这里以Netty Remote为例总结一些Client和Server的基本流程。

Client:通过HeaderExchanger调用connect方法 new HeaderExchangeClient(Transporters.connect(url, new DecodeHandler(new HeaderExchangeHandler(handler)))); —》NettyTransporter 调用connect方法 new NettyClient(url, listener)。这样一个连接就诞生了。

Server: 通过HeaderExchanger调用bind方法 new HeaderExchangeServer(Transporters.bind(url, new DecodeHandler(new HeaderExchangeHandler(handler)))); —》NettyTransporter 调用bind方法 new NettyServer(url, listener)。这样监听诞生。

框架代码设计小技巧

1 引入使用频率较高第三方类库时,如果类库比较小如fastjson, asm类库为了防止jar冲突,可以直接把源码copy到项目中;

2 在设计抽象类时,比如dubbo的AbstractClient,比如方法的一些公共部分抽离出来,不确定的部分包到抽象方法里,留给子类实现;方法的命名很有技巧 比如 方法open里已知的逻辑我们写直接在抽象类里写,要留给子类的逻辑我们起个抽象方法doOpen。
输入图片说明

https://my.oschina.net/robinyao/blog/804182

下节介绍dubbo rpc层的逻辑。

© 著作权归作者所有

共有 人打赏支持
robin-yao
粉丝 151
博文 54
码字总数 61496
作品 0
杭州
加载中

评论(5)

h
hahaee
请问你这类关系图怎么弄得? idea里的diagrams没有这么详细的图啊
老范的自留地
老范的自留地
不错
robin-yao
robin-yao

引用来自“chrischeng03”的评论

其实只需了解netty3.5就明白了,基本是仿照和抄的
差不多吧,学习学习里面的代码也是不错的。:smile:
c
chrischeng03
duubo并不怎么神秘,里层代码就是Proxy加netty抄和hisssion抄
c
chrischeng03
其实只需了解netty3.5就明白了,基本是仿照和抄的
dubbo剖析:七 网络通信总结

注:文章中使用的dubbo源码版本为2.5.4 零、文章目录 Dubbo的网络分层抽象 Dubbo如何保证Client端与Server端的连通性 Dubbo的请求响应模式,如何将异步IO变为同步RPC Dubbo线程模型总结 一、...

益文的圈
05/13
0
0
dubbo源码分析系列——项目工程结构介绍

项目源码地址 本系列文章是基于当当网维护的dubbox版本进行分析的,源码地址参考:https://github.com/dangdangdotcom/dubbox 项目源码结构 我们下载源码后导入到ide中可以看到如此之多的项目...

杨武兵
2016/05/29
745
0
dubbo源码学习笔记----整体结构

dubbo核心包 config dubbo-config-api dubbo-config-spring remoting dubbo-remoting-netty dubbo-remoting-netty4 dubbo-remoting-mina dubbo-remoting-grizzly dubbo-remoting-p2p dubbo-......

春哥大魔王的博客
01/13
0
0
Dubbo入门笔记(一)

开发环境 笔记仅供参考,具体开发环境可能存在版本差异。 OS:Windows 10 JDK:SUN 1.8 Eclipse:4.5[STS Spring定制版] Maven:3.3.9 Dubbo 服务治理(SOA)治理框架 Duboo是一个分布式服务框架 ...

z201
2016/09/11
126
0
dubbo源码分析系列(4)dubbo通信设计

1 系列目录 - dubbo源码分析系列(1)扩展机制的实现- dubbo源码分析系列(2)服务的发布- dubbo源码分析系列(3)服务的引用- dubbo源码分析系列(4)dubbo通信设计 2 NIO通信层的抽象 目前...

乒乓狂魔
2015/10/26
5.7K
5

没有更多内容

加载失败,请刷新页面

加载更多

下一页

新工作与老项目

新的工作不知不觉的干了一个多月了。怎么说呢,跟想象中的差别不少,本来想的能进来跟大公司的同事能有很多交流,能在团队中跟大牛学习更快。结果公司的这个项目上只有两个程序员,项目是十年...

zypy333
11分钟前
0
0
mysql 在windows的安装

mysql 在windows的安装。 mysql64位的server的下载地址是: https://dev.mysql.com/downloads/mysql/ 使用的是5.7版本。 下载安装包,解压至D:\mysql\mysql-5.7.23-winx64\ 在D:\mysql\mysq...

lxzh504
24分钟前
1
0
云技术、大数据(hadoop)入门常见问题回答

当我们学习一门新技术的时候,我们总是产生各种各样的问题,这些问题整理出来,包括该 1.如何学习hadoop? 2.hadoop常见问题? 3.还有hbase、hive安装使用等? 你知道搭建hadoop平台需要些什...

董黎明
24分钟前
1
0
小程序自定义底部tab

场景 1.tabBar是在内页而非首页,这时就不得不自定义一个tabBar了 2.自定义风格 3.子页数量超过5个,得到更多了tab 4.改变点击tab默认事件,比如出登录界面,或者弹出上拉子菜单等 步骤 1.照...

萤火的萤火
29分钟前
1
0
shell炫技

1.为脚本添加“--help” #!/bin/shif [ ${#@} -ne 0 ] && [ "${@#"--help"}" = "" ]; then printf -- '...help...\n'; exit 0;fi; 2.输出字体添加颜色 https://misc.flogisoft.com......

HJCui
30分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部