Dubbo-聊聊通信模块设计

前言Dubbo源码阅读分享系列文章,欢迎大家关注点赞
SPI实现部分

  1. Dubbo-SPI机制
  2. Dubbo-Adaptive实现原理
  3. Dubbo-Activate实现原理
  4. Dubbo SPI-Wrapper
注册中心
  1. Dubbo-聊聊注册中心的设计
通信模块介绍Dubbo通信模块主要的目的就是解决客户端以服务端通信的问题,核心代码都在dubbo-remoting模块,该模块提供了多种客户端和服务端通信的功能 。Dubbo的通信主要包括是三部分:Exchange、Transport和Serialize,对于序列化部分的设计在单独的模块中,我们再单独聊,这篇文章主要聊Exchange、Transport设计 。对于Dubbo来说没有自己的网络框架,使用现有第三方类库,因此需要设计一套标准API来兼容多种不同的通信框架,dubbo-remoting 模块的结构就是目前Dubbo兼容的所有的通信框架 。在整体模块设计上,dubbo-remoting-api是其他模块上层抽象,其他子模块都是依赖第三方NIO库实现 dubbo-remoting-api模块的 。因此我们想要了解清楚dubbo-remoting设计必须要理解dubbo-remoting-api的设计 。对于dubbo-remoting-api大致可以分为四类,
  1. 核心API设计,主要是包括端口、编码、解码等等核心接口的抽象;
  2. buffer,主要是定义缓冲区相关的接口、抽象类以及实现类;
  3. exchange,抽Request和Response概念抽象以及扩展;
  4. transport,网络传输层的抽象,但它只负责消息的传输;
源码分析核心API设计EndpointEndpoint被翻译端点,这里可以理解为通信中对IP和Port的抽象,Client和Server端共同的抽象,两个端通过Endpoint建立TCP连接,进行通信 。对于该Endpoint接口定义了三类方法:
  1. get类方法,主要获取Endpoint的本地地址、关联的URL信息以及底层Channel关联的ChannelHandle,也就是获取建立连接需要的属性;
  2. send方法主要负责发送数据;
  3. close类方法,主要是用来关闭连接;
ChannelChannel可以理解为Client和Server端连接的通道,是NIO框架设计中不可缺少的概念,Channel继承Endpoint,因此拥有Endpoint的能力,对于Channel来说,可以给自身设计一些额外属性 。
ChannelHandlerChannelHandler可以理解为Channel的处理器,ChannelHandler 可以处理Channel的连接建立以及连接断开事件,还可以处理读取到的数据、发送的数据以及捕获到的异常 。
Codec2Codec2实现编码和解码,实现字节与消息体之间的转换,类似Netty中编码和解码 。此外,Codec2接口被@SPI 接口修饰了,说明该接口是一个扩展接口,同时encode方法和 decode方法都被@Adaptive注解修饰,因此也会生成适配器类,可以根据URL中的codec值确定具体的扩展实现类,这里就体现SPI和URL灵活配置的特性 。
@SPIpublic interface Codec2 {    @Adaptive({Constants.CODEC_KEY})    void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException;    @Adaptive({Constants.CODEC_KEY})    Object decode(Channel channel, ChannelBuffer buffer) throws IOException;    enum DecodeResult {        NEED_MORE_INPUT, SKIP_SOME_INPUT    }}此外还存在DecodeResult的枚举,该枚举是处理粘包和拆包使用的 。
ClientClient继承了Endpoint、Channel等相关的接口,因此对于Client也具备收发消息能力,Client只可以关联一个 Channel 。
RemotingServerServer与Client不太一样地方就是可以接收多个Client发起的Channel连接,因此RemotingServer接口中存在获取多个Channel列表的接口 。

经验总结扩展阅读