dubbo源码深度解读四之remoting模块
来源:互联网 发布:通达信原油看盘软件 编辑:程序博客网 时间:2024/06/06 08:44
前言:remoting模块是远程通讯模块,相当于Dubbo协议的实现,是一个为Dubbo项目处理底层网络通信的层。具体结合了netty,mina等进行实现。
一,dubbo-remoting-api
首先结合文档的图先了解一下基础接口包的主要类。
1,ChannelHandler是抽象的通道事件处理器,同时注意到它的注解也是SPI
@SPIpublic interface ChannelHandler { void connected(Channel channel) throws RemotingException; void disconnected(Channel channel) throws RemotingException; void sent(Channel channel, Object message) throws RemotingException; void received(Channel channel, Object message) throws RemotingException; void caught(Channel channel, Throwable exception) throws RemotingException;}
2,Codec2.接口定义了编码解码规范,与废弃的接口Codec相比,Codec2没有依赖jdk的输入输出流, 以dubbo的ChannelBuffer为核心便于更好的整合(关于各个Codec2的实现类例如DubboCodec,会和rpc模块一起深入解读)
@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 }}
3,Transporter
bind 根据URL和ChannelHandler 生成Server, connect 根据URL和ChannelHandler
@SPI("netty")public interface Transporter { @Adaptive({Constants.SERVER_KEY, Constants.TRANSPORTER_KEY}) Server bind(URL url, ChannelHandler handler) throws RemotingException; @Adaptive({Constants.CLIENT_KEY, Constants.TRANSPORTER_KEY}) Client connect(URL url, ChannelHandler handler) throws RemotingException;}
4,Endpoint。Client和Server都继承的一个接口类
5,Dispatcher。定义channelHandler对Channel的操作(哪些走线程池)
@SPI(AllDispatcher.NAME) public interface Dispatcher { @Adaptive({Constants.DISPATCHER_KEY, "dispather", "channel.handler"}) // 后两个参数为兼容旧配置 ChannelHandler dispatch(ChannelHandler handler, URL url); }
二,服务端集成netty
1,先看下NettyServer的类图
2,处理流程
其中Netty区域的类,都是扩展了了Netty自带类。
1.1 InternalDecoder:负责TCP层协议的解析,处理TCP粘包。(当然这个解析也包含序列化的处理)。
1.2 InternalEncoder: 协议封装。
1.3 NettyHandler:客户通道共享的处理器(请参阅Netty的通道处理器模型),转换Netty的通道事件到Dubbo事件。
1.4 NettyServer:处理连接数量。
1.5 MultiMessageHandler:多消息处理。
1.6 HeartbeatHandler:心跳消息。
1.7 AllChannelHandler:委派业务请求到线程池。
3,NettyHandler的实现
继承org.jboss.netty.channel.SimpleChannelHandler,来处理org.jboss.netty.channel.Channel的连接读写事件。此时NettyHandler就可以委托dubbo的com.alibaba.dubbo.remoting.ChannelHandler接口实现来完成具体的功能,在交给com.alibaba.dubbo.remoting.ChannelHandler接口实现之前,需要先将netty自己的org.jboss.netty.channel.Channel channel转化成上述的NettyChannel。
其实就是相当于转换Netty的通道事件到Dubbo事件
摘取部分代码来看一下就知道了
@Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { NettyChannel channel = NettyChannel.getOrAddChannel(ctx.getChannel(), url, handler); try { if (channel != null) { channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.getChannel().getRemoteAddress()), channel); } //转换到ChannelHandler的connected handler.connected(channel); } finally { NettyChannel.removeChannelIfDisconnected(ctx.getChannel()); } }
4,NettyServer启动流程
按照netty自己的API启动方式,然后依据外界传递进来的com.alibaba.dubbo.remoting.ChannelHandler接口实现,创建出NettyHandler,最终对用户的连接请求的处理全部交给NettyHandler来处理,NettyHandler又交给了外界传递进来的com.alibaba.dubbo.remoting.ChannelHandler接口实现。
至此就将所有底层不同的通信实现全部转化到了外界传递进来的com.alibaba.dubbo.remoting.ChannelHandler接口的实现上了。
而上述Server接口的另一个分支实现HeaderExchangeServer则充当一个装饰器的角色,为所有的Server实现增添了如下功能:
向该Server所有的Channel依次进行心跳检测:
- 如果当前时间减去最后的读取时间大于heartbeat时间或者当前时间减去最后的写时间大于heartbeat时间,则向该Channel发送一次心跳检测
- 如果当前时间减去最后的读取时间大于heartbeatTimeout,则服务器端要关闭该Channel,如果是客户端的话则进行重新连接(客户端也会使用这个心跳检测任务)
三,客户端集成Netty
服务器端了解了之后,客户端就也非常清楚了,整体类图如下:
NettyClient在使用netty的API开启客户端之后,仍然使用NettyHandler来处理。还是最终转化成com.alibaba.dubbo.remoting.ChannelHandler接口实现上了。
我们可以看到这样集成完成之后,就完全屏蔽了底层通信细节,将逻辑全部交给了com.alibaba.dubbo.remoting.ChannelHandler接口的实现上了。从上面我们也可以看到,该接口实现也会经过层层装饰类的包装,才会最终交给底层通信。
- dubbo源码深度解读四之remoting模块
- dubbo源码深度解读一之common模块
- dubbo源码深度解读二之config模块
- dubbo源码深度解读三之container模块
- dubbo源码深度解读五之rpc模块
- dubbo源码深度解读六之cluster模块
- dubbo源码深度解读七之registery模块
- dubbo源码深度解读一之common模块
- dubbo源码分析-RPC远程调用模块与Remoting通讯模块协作细节
- Dubbo ExtensionLoader源码解读
- dubbo源码解读
- Dubbo源码分析(四):Dubbo之Registry
- Dubbo源码分析(四):Dubbo之Registry
- dubbo 源码学习笔记 (四) —— 配置模块
- 深度解剖dubbo源码
- 深度解剖dubbo源码
- 深度解剖dubbo源码
- dubbo源码阅读-remoting 设计模式
- MySQL(二)
- LDA 视频收藏描述 预测分类
- struts2 文件上传
- git stash的使用
- 1087. All Roads Lead to Rome (30)
- dubbo源码深度解读四之remoting模块
- 中缀转后缀——逆波兰表示
- 【C语言】条件编译
- SELECT中OPTION元素的显示隐藏
- 【Java并发编程】Executor Interfaces
- Android 集成 FFmpeg (一) 基础知识及简单调用
- CSDN上怎么粘贴有格式的代码
- 【自考】网络第四章总结
- mac 反编译apk