文档章节

Dubbo源码分析-Remoting层

robin-yao
 robin-yao
发布于 2016/12/11 21:56
字数 1795
阅读 660
收藏 33
点赞 1
评论 5

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
粉丝 146
博文 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

dubbo源码分析系列——项目工程结构介绍

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

杨武兵 ⋅ 2016/05/29 ⋅ 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

Dubbo入门笔记(一)

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

z201 ⋅ 2016/09/11 ⋅ 0

dubbo Servlet Bridge Server时同时支持hessian和webservice

原生的bubbo在发布hessian和webservice时使用了嵌入jetty的方式开启了两个端口。 而考虑到我们实际的情况,需要使用weblogic发布,并且是使用同一个端口对外提供服务。 所以我们要扩展dubbo...

linan ⋅ 2015/10/13 ⋅ 0

dubbo 请求调用过程分析

服务消费方发起请求 当服务的消费方引用了某远程服务,服务的应用方在spring的配置实例如下: demoService实例其实是代理工厂生产的代理对象(大家可以参考代理那部分生成的伪代码),在代码...

赵蕊 ⋅ 2017/06/07 ⋅ 1

dubbo中的那些“坑"(3)-netty4-rpc网络接口中的高并发的bug

在几个月前改造dubbo时,netty4已经稳定很久了,一时手痒,按照netty3-rpc的源码克隆了一套netty4,在修正了大量的包、类型不同之后,基本保持了netty3的风格,并发量小或者数据包很小时,一...

阿阮 ⋅ 2014/12/02 ⋅ 10

dubbo源码分析系列(4)dubbo通信设计

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

乒乓狂魔 ⋅ 2015/10/26 ⋅ 5

dubbo框架基本分析

dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。其核心部分包含: 远程通讯: 提供对多种基于长连接的NIO框架抽象封装,包括多种线程模型,...

火龙战士 ⋅ 2016/06/21 ⋅ 0

dubbo源码分析系列——dubbo-rpc-default模块源码分析

简化类图 从图中可以看出该模块下的类主要是实现了dubbo-rpc-api和dubbo-remoting-api两个模块中定义的一些接口和抽象类。扩展了一种duubo框架自定义的dubbo协议,包括编解码和方法调用处理等...

杨武兵 ⋅ 2016/05/31 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RabbitMQ学习以及与Spring的集成(三)

本文介绍RabbitMQ与Spring的简单集成以及消息的发送和接收。 在RabbitMQ的Spring配置文件中,首先需要增加命名空间。 xmlns:rabbit="http://www.springframework.org/schema/rabbit" 其次是模...

onedotdot ⋅ 25分钟前 ⋅ 0

JAVA实现仿微信红包分配规则

最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。 算法介绍 一、红包金额限制 对于微...

小致dad ⋅ 37分钟前 ⋅ 0

Python 数电表格格式化 xlutils xlwt xlrd的使用

需要安装 xlutils xlwt xlrd 格式化前 格式化后 代码 先copy读取的表格,然后按照一定的规则修改,将昵称中的学号提取出来替换昵称即可 from xlrd import open_workbookfrom xlutils.copy ...

阿豪boy ⋅ 今天 ⋅ 0

面试题:使用rand5()生成rand7()

前言 读研究生这3 年,思维与本科相比变化挺大的,这几年除了看论文、设计方案,更重要的是学会注重先思考、再实现,感觉更加成熟吧,不再像个小P孩,人年轻时总会心高气傲。有1 道面试题:给...

初雪之音 ⋅ 今天 ⋅ 0

Docker Toolbox Looks like something went wrong

Docker Toolbox 重新安装后提示错误:Looks like something went wrong in step ´Checking if machine default exists´ 控制面板-->程序与应用-->启用或关闭windows功能:找到Hyper-V,如果处......

随你疯 ⋅ 今天 ⋅ 0

Guacamole 远程桌面

本文将Apache的guacamole服务的部署和应用,http://guacamole.apache.org/doc/gug/ 该链接下有全部相关知识的英文文档,如果水平ok,可以去这里仔细查看。 一、简介 Apache Guacamole 是无客...

千里明月 ⋅ 今天 ⋅ 0

nagios 安装

Nagios简介:监控网络并排除网络故障的工具:nagios,Ntop,OpenVAS,OCS,OSSIM等开源监控工具。 可以实现对网络上的服务器进行全面的监控,包括服务(apache、mysql、ntp、ftp、disk、qmail和h...

寰宇01 ⋅ 今天 ⋅ 0

AngularDart注意事项

默认情况下创建Dart项目应出现以下列表: 有时会因为不知明的原因导致列表项缺失: 此时可以通过以下步骤解决: 1.创建项目涉及到的包:stagehand 2.执行pub global activate stagehand或pub...

scooplol ⋅ 今天 ⋅ 0

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部