dubbo源码深度解读四之remoting模块

前言:remoting模块是远程通讯模块,相当于Dubbo协议的实现,是一个为Dubbo项目处理底层网络通信的层。具体结合了netty,mina等进行实现。

一,dubbo-remoting-api
首先结合文档的图先了解一下基础接口包的主要类。
dubbo源码深度解读四之remoting模块_第1张图片
1,ChannelHandler是抽象的通道事件处理器,同时注意到它的注解也是SPI

@SPI
public 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模块一起深入解读)

@SPI
public 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的类图
dubbo源码深度解读四之remoting模块_第2张图片

2,处理流程
dubbo源码深度解读四之remoting模块_第3张图片
其中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启动流程
dubbo源码深度解读四之remoting模块_第4张图片
按照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
服务器端了解了之后,客户端就也非常清楚了,整体类图如下:
dubbo源码深度解读四之remoting模块_第5张图片
NettyClient在使用netty的API开启客户端之后,仍然使用NettyHandler来处理。还是最终转化成com.alibaba.dubbo.remoting.ChannelHandler接口实现上了。
我们可以看到这样集成完成之后,就完全屏蔽了底层通信细节,将逻辑全部交给了com.alibaba.dubbo.remoting.ChannelHandler接口的实现上了。从上面我们也可以看到,该接口实现也会经过层层装饰类的包装,才会最终交给底层通信。

你可能感兴趣的:(dubbo,rpc)