文档章节

Dubbo源码分析-Remoting层

robin-yao
 robin-yao
发布于 2016/12/11 21:56
字数 1795
阅读 705
收藏 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
粉丝 157
博文 53
码字总数 60598
作品 0
杭州
私信 提问
加载中

评论(5)

h
hahaee
请问你这类关系图怎么弄得? idea里的diagrams没有这么详细的图啊
_凤求凰_
_凤求凰_
不错
robin-yao
robin-yao

引用来自“chrischeng03”的评论

其实只需了解netty3.5就明白了,基本是仿照和抄的
差不多吧,学习学习里面的代码也是不错的。😄
c
chrischeng03
duubo并不怎么神秘,里层代码就是Proxy加netty抄和hisssion抄
c
chrischeng03
其实只需了解netty3.5就明白了,基本是仿照和抄的
Dubbo (三)源码分析 —— 架构原理

1 核心功能 首先要了解Dubbo提供的三大核心功能: Remoting:远程通讯 提供对多种NIO框架抽象封装,包括“同步转异步”和“请求-响应”模式的信息交换方式。 Cluster: 服务框架 提供基于接口方...

小刀爱编程
10/18
0
0
Dubbo (二) ——- 项目结构解析

本文主要说明点 概述 背景 需求 架构 Dubbo源代码项目结构 概述 分享 Dubbo 的项目结构 ,通过本文可以大致了解到Dubbo整个项目的结构 背景 将一个项目进行拆分, 进行分布式架构。 需要解决...

小刀爱编程
10/16
0
0
dubbo剖析:七 网络通信总结

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

益文的圈
05/13
0
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源码分析系列——项目工程结构介绍

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

杨武兵
2016/05/29
745
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS配置Tomcat监听80端口,虚拟主机

Tomcat更改默认端口为80 更改的配置文件是: /usr/local/tomcat/conf/server.xml [root@test-a ~]# vim /usr/local/tomcat/conf/server.xml # 找到 Connector port="8080" protocol="HTTP/1......

野雪球
今天
5
0
《稻盛和夫经营学》读后感心得体会3180字范文

《稻盛和夫经营学》读后感心得体会3180字范文: 一代日本经营之圣稻盛和夫凭借刻苦勤奋的精神以及深植于佛教的商业道德准则,成为了“佛系”企业家的代表人物。在《稻盛和夫经营学》“领导人...

原创小博客
今天
3
0
java框架学习日志-5(常见的依赖注入)

依赖注入(dependency injection) 之前提到控制反转(Inversion of Control)也叫依赖注入,它们其实是一个东西,只是看的角度不同,这章详细说一下依赖注入。 依赖——指bean对象创建依赖于...

白话
今天
4
0
红外接收器驱动开发

背景:使用系统的红外遥控软件没有反应,然后以为自己接线错误,反复测试,结果烧坏了一个红外接收器,信号主板没有问题。所以自己开发了一个红外接收器的python驱动。接线参见https://my.os...

mbzhong
今天
2
0
ActiveMQ消息传送机制以及ACK机制详解

AcitveMQ是作为一种消息存储和分发组件,涉及到client与broker端数据交互的方方面面,它不仅要担保消息的存储安全性,还要提供额外的手段来确保消息的分发是可靠的。 一. ActiveMQ消息传送机...

watermelon11
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部