Dubbo源码解析-网络通信

1,062 阅读10分钟

1.Transport层实现解析

       根据Dubbo框架分层,Transporter与Serializase层主要用于真正的网络通信传输与通信内容的序列化,主要是现在remoting/transport包中,经过对Exchanger层的实现讲解,可以知道网络通信都可以抽象为Server/Client/Channel/ChannelHandler几个主要概念,在transport中使用各种Abstract抽象类针对不同的通信框架的封装,通信框架如netty/grizzly/mina等。其中传输的接口设计如下所示,这是一个扩展点,默认实现为NettyTransporter类。在Exchange层次初始化时会使用Transporters类,这里返回NettyClient和NettyServer对象。

public interface Transporter {

    @Adaptive({Constants.SERVER_KEY, Constants.TRANSPORTER_KEY})
    RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException;

    @Adaptive({Constants.CLIENT_KEY, Constants.TRANSPORTER_KEY})
    Client connect(URL url, ChannelHandler handler) throws RemotingException;
}

public class Transporters {    
    ...
    public static RemotingServer bind(String url, ChannelHandler... handler) {
        return bind(URL.valueOf(url), handler);
    }
    public static Client connect(URL url, ChannelHandler... handlers) {
        return getTransporter().connect(url, handler);
    }
    public static Transporter getTransporter() {
        //加载Transporter的扩展实现类
        return ExtensionLoader.getExtensionLoader(Transporter.class)
                .getAdaptiveExtension();
    }
    ...
}

public class NettyTransporter implements Transporter {
    @Override
    public RemotingServer bind(URL url, ChannelHandler handler)
             throws RemotingException {
        //返回Netty实现的服务器实例
        return new NettyServer(url,g handler);
    }

    @Override
    public Client connect(URL url, ChannelHandler handler) 
            throws RemotingException {
        //返回Netty实现的客户端实例
        return new NettyClient(url, handler);
    }
}

1.1 服务器与客户端设计解析

        服务端和客户端都采用了模版设计方法,提供了AbstractServer,AbstractClient,分别指定了服务端和客户端实现的一个基本框架,具体实类逻辑如下所示,底层通过Channel进行实际网络通信。创建服务端对象实例,具体实现类实现抽象方法doOpen,完成实际服务端实例创建。

public abstract class AbstractServer extends AbstractEndpoint 
            implements RemotingServer {
    ...
    public AbstractServer(URL url, ChannelHandler handler) throws RemotingException {
        super(url, handler);
        ...
        try {
            doOpen();
            ...
        } catch (Throwable t) {
            ...
        }
        executor = executorRepository.createExecutorIfAbsent(url);
    }
    //抽象方法,留给继承的子类实现
    protected abstract void doOpen() throws Throwable;
}

        服务端接收连接,调用实现类中的getChannels方法判断是否超过了最大可接收连接数,然后在调用AbstractPeer#connected来处理Channel创建/断开逻辑。

public abstract class AbstractServer extends AbstractEndpoint 
            implements RemotingServer {

    @Override
    public void connected(Channel ch) throws RemotingException {
        ...
        Collection<Channel> channels = getChannels();
        if (accepts > 0 && channels.size() > accepts) {
          ...
            ch.close();
            return;
        }
        super.connected(ch);
    }
}

public abstract class AbstractPeer implements Endpoint, ChannelHandler {
   @Override
   public void connected(Channel ch) throws RemotingException 
        //这里是构造好的处理器实例
        handler.connected(ch);    
   }
}

       在客户端实现中,可以查看AbstractClient的相关方法。这里在初始化时通过connectLock重入锁实现线程并发控制,抽象方法doConnect由具体实现类实现特定的连接逻辑。

 public abstract class AbstractClient extends AbstractEndpoint implements Client {
    public AbstractClient(URL url, ChannelHandler handler) throws RemotingException {
        super(url, handler);
        ...
        try {
           //调用抽象方法
            doOpen();
        } catch (Throwable t) {
            close();
        }
            
        try {
            connect();
        } catch (RemotingException t) {
            ...
        } catch (Throwable t) {
            ...
        }
    }

    protected void connect() throws RemotingException {
        //上锁,避免线程同步问题
        connectLock.lock();
        try {
            if (isConnected()) {
                return;
            }
            doConnect();
        } catch (RemotingException e) {
            throw e;
        } catch (Throwable e) {
            ...
        } finally {
            //释放锁
            connectLock.unlock();
        }
    }
    protected abstract void doConnect() throws Throwable;
}

      客户端在发送信息时,回先判断客户端是否已连接上服务端,如果没有则进行连接,如果有则调用子类具体的send方法发送信息。

public abstract class AbstractClient extends AbstractEndpoint implements Client {
    
    @Override
    public void send(Object message, boolean sent) throws RemotingException {
        //判断是否需要连接
        if (needReconnect && !isConnected()) {
            connect();
        }
        //通过子类返回实现的信道
        Channel channel = getChannel();
        //发送信息
        channel.send(message, sent);
    }
    protected abstract Channel getChannel();
}

以Netty实现的服务端与客户端为例,在netty信道初始化时会将编解码器和处理类设置上去,这样每条信道的处理都会经过这些编解码和处理类去处理。

public class NettyClient extends AbstractClient {

    public NettyClient(final URL url, final ChannelHandler handler) 
            throws RemotingException {
         //进行处理链初始化
         super(url, wrapChannelHandler(url, handler));
    }

    @Override
    protected void doOpen() throws Throwable {

        final NettyClientHandler nettyClientHandler = new NettyClientHandler(getUrl(), this);
        ...
        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
               //初始化编解码器
                NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);
                //初始化pipeline,设置编解码器和处理类
                ch.pipeline()
                        .addLast("logging",new LoggingHandler(LogLevel.INFO))
                        .addLast("decoder", adapter.getDecoder())
                        .addLast("encoder", adapter.getEncoder())
                        .addLast("handler", nettyClientHandler);
            }
        });
        ...
    }
}

public class NettyServer extends AbstractServer implements RemotingServer {
      
    ...
    @Override
    protected void doOpen() throws Throwable {        
                bootstrap.group(bossGroup, workerGroup)
                .channel(NettyEventLoopFactory.serverSocketChannelClass())
                .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)
                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ....
                        //初始化pipeline,设置编解码器和处理类
                        ch.pipeline()
                                .addLast("decoder", adapter.getDecoder())
                                .addLast("encoder", adapter.getEncoder())
                                .addLast("server-idle-handler", 
                                    new IdleStateHandler(0, 0, idleTimeout, MILLISECONDS))
                                .addLast("handler", nettyServerHandler);
                    }
                });
   }
}

1.2 信道处理实现解析

在网络通信中,双方建立连接后,在Dubbo框架中抽象为ChannelHandler,来处理通信信道的创建/断开/消息发送/消息接收/信道异常等情况,Dubbo中提供了大量的Handler去承载特性和扩展,这些Handler最终会和底层通信框架做关联,如netty等。一次完整的RPC调用贯穿了一系列的Handler,如果直接挂载到底层框架中,会造成处理链路过程,并会触发大量链式查找和事件,不仅低效,而且浪费资源。

@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;
}

一些常用处理类如下所示。

  • ExchangeHandlerAdapter: 用于查找微服务方法调用;
  • HeaderExchangeHandler:用于封装处理Request和Response
  • DecodeHandler: 支持在Dubbo线程池中做解码
  • ChannelHandlerDisptcher: 封装多Handler广播调用
  • AllChannelHandler: 支持Dubbo线程池调用业务方法
  • HeartbeatHandler: 支持心跳处理
  • MultiMessageHandler: 支持流中多消息报文批处理
  • ConnnectionOrderedChannelHandler: 单独线程池处理TCP的连接和断开
  • MessageOnlyChannelHandler: 仅在线程池处理接收报文,其他事件在I/O线程处理
  • WrappedChannelHandler: 基于内存key-value存储封装和共享线程池能力,比如记录线程池等
  • NettyServerHandler: 封装Netty服务端事件,处理连接、断开、读取、写入和异常等
  • NettyClientHandler: 封装Netty客户端事件,处理连接、断开、读取、写入和异常等

      HeaderExchangeHandler处理类, HeaderExchangeHandler的下一个处理节点是ExchangeHandlerAdapter处理类。通过代理类的包装后,就可以以责任链处理的方式将这些处理器连接起来。

public interface ChannelHandlerDelegate extends ChannelHandler {
    ChannelHandler getHandler();
}

//Handler代理抽象类,可设置责任链下一个节点
public abstract class AbstractChannelHandlerDelegate 
        implements ChannelHandlerDelegate {
    protected ChannelHandler handler;
    protected AbstractChannelHandlerDelegate(ChannelHandler handler) {
        this.handler = handler;
    }

    @Override
    public ChannelHandler getHandler() {
        if (handler instanceof ChannelHandlerDelegate) {
            return ((ChannelHandlerDelegate) handler).getHandler();
        }
        return handler;
    }
}

        最终效果如下所示,在ChannelPipeline里面将这个处理链路设置上去,在通信内容入站和出战的时候都经过这些处理类,进行依次处理。

public class ChannelHandlers {

    public static ChannelHandler wrap(ChannelHandler handler, URL url) {
        return ChannelHandlers.getInstance().wrapInternal(handler, url);
    }

    protected ChannelHandler wrapInternal(ChannelHandler handler, URL url) {
        return new MultiMessageHandler(new HeartbeatHandler
                (ExtensionLoader.getExtensionLoader(Dispatcher.class)
                .getAdaptiveExtension().dispatch(handler, url)));
    }
}

         Dispatcher是线程池分发器,可以理解为拥有线程池分发能力的ChannelHandler,比如AllChannelHandler、 MessageOnlyChannelHandler和ExcutionChannelHandler等,其本身并不具备线程派发能力。Dispatcher属于Dubbo的扩展点,用来生成动态的Handler,以满足不同的使用场景,其中Dubbo支持以下几种分发策略。

@SPI(AllDispatcher.NAME)
public interface Dispatcher {

    @Adaptive({Constants.DISPATCHER_KEY, "dispather", "channel.handler"})
    ChannelHandler dispatch(ChannelHandler handler, URL url);

}
  • AllDispatcher: 将所有I/O事件交给Dubbo线程池处理,Dubbo默认启用;
  • Connection: 单独线程池处理连接断开事件,和Dubbo线程池分开;
  • DirectDispatcher: 所有方法调用和事件处理都在I/O线程中;
  • MessageOnlyChannelHandler: 只在线程池处理请求和响应事件,其他都在I/O线程池中;
  • MockDispatcher: 默认返回.

与线程池分发紧密相关的是线程池的实现,Dubbo框架中线程池ThreadPool也是一个SPI扩展点,有FixedThreadPool/LimitedThreadPool等多种具体实现,可以根据URL的相关参数决定使用具体的线程池实现。在一个应用中可以有多个线程池的,这里使用了DefaultExecutorRepository存储,在AbstractServer/AbstractClient中会调用DefaultExecutorRepository#createExecutorIfAbsent来创建线程池。

@SPI("fixed")
public interface ThreadPool {

    //根据URL上的threadpool参数决定
    @Adaptive({THREADPOOL_KEY})
    Executor getExecutor(URL url);

}

public class DefaultExecutorRepository implements ExecutorRepository {

    public synchronized ExecutorService createExecutorIfAbsent(URL url) {
        String componentKey = EXECUTOR_SERVICE_COMPONENT_KEY;
        if (CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(SIDE_KEY))) {
            componentKey = CONSUMER_SIDE;
        }
       ExecutorService executor = 
        executors.computeIfAbsent(portKey, k -> createExecutor(url));
        return executor;
    }
    
    //根据URL创建线程池
    private ExecutorService createExecutor(URL url) {
        return (ExecutorService) ExtensionLoader
            .getExtensionLoader(ThreadPool.class).getAdaptiveExtension()
            .getExecutor(url);
    }
}


public abstract class AbstractServer extends 
        AbstractEndpoint implements RemotingServer {

    public AbstractServer(URL url, ChannelHandler handler) 
        throws RemotingException {
    ...
    //初始化服务端线程池
    executor = executorRepository.createExecutorIfAbsent(url);
}

Dubbo框架提供了几种不同线程池实现:

  • FixedThreadPool:创建一个复用固定个数线程的线程池;
  • LimitedThreadPool:创建一个线程池,这个线程池中线程个数随着需要量动态增加,但是数量不超过配置的阈值的个数,另外空闲线程不会被回收,会一直存在;
  • EagerThreadPool :创建一个线程池,这个线程池当所有核心线程都处于忙碌状态时候,创建新的线程来执行新任务,而不是把任务放入线程池阻塞队列;
  • CachedThreadPool:创建一个自适应线程池,当线程处于空闲1分钟时候,线程会被回收,当有新请求到来时候会创建新线程。

2. 协议解析和编解码实现原理

2.1 Dubbo协议解析

高效精巧的通信协议设计直接决定了框架通信的性能、稳定性与扩展性等。Dubbo协议设计参考了现有的TCP/IP协议,主要可分为协议头和协议体两部分。

  • 报文头: 长度为16字节,其中包括了魔数(0xdabb)用来处理分割黏包处理,当前请求报文是Request、Response、心跳和事件的信息,当前报文体内的序列化协议编号,请求状态,请求唯一标识ID,报文体长度信息。
  • 协议体: 包括dubbo版本、服务名、服务版本、方法名、方法参数类型、方法参数等内容。

2.2 编码实现解析

Codec2中已经定义了I/O的编解码过程,主要方法是encode和decode定义如下所示。

@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;
}

         其中主要的实现类有以下几个,其中AbstractCodec主要提供基础能力,比如校验报文长度和查找具体编解码等,DubboCodec继承ExchangeCodec,而ExchangeCodec又继承了TelnetCodec实现。 

       Dubbo的RPC请求构造中,编码器主要对Java对象编码编程字节流返回到处于上层的客户端,包括了构造报文的头部,然后对消息体进行序列化。所有的报文头的处理的实现都在ExchangeCodec#encode中,包括了请求和回复两种编码处理。

public class ExchangeCodec extends TelnetCodec {

    @Override
    public void encode(Channel channel, ChannelBuffer buffer, Obj ect msg) throws IOException {
        if (msg instanceof Request) {
            encodeRequest(channel, buffer, (Request) msg);
        } else if (msg instanceof Response) {
            encodeResponse(channel, buffer, (Response) msg);
        } else {
            super.encode(channel, buffer, msg);
        }
    }

    protected void encodeRequest(Channel channel,
             ChannelBuffer buffer, Request req) throws IOException {

        //获取指定或默认的序列化协议
        Serialization serialization = getSerialization(channel);
        //构造16字节头
        byte[] header = new byte[HEADER_LENGTH];
        //占用两个字节的魔法数,用来处理半包黏包
        Bytes.short2bytes(MAGIC, header);
        //在第三个字节
        header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId());
    
        ....        

        //设置请求唯一标识
        Bytes.long2bytes(req.getId(), header, 4);
        int savedWriteIndex = buffer.writerIndex();
        //跳过报文头的16个字节
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);

        ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
        //进行序列化
        ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
        if (req.isEvent()) {
            encodeEventData(channel, out, req.getData());
        } else {
            //交给子类重写方法去实现
            encodeRequestData(channel, out, req.getData(), req.getVersion());
        }
        
        ...

        int len = bos.writtenBytes();
        //检查是否超过默认8MB大小
        checkPayload(channel, len);
        //将消息长度写入头部的第12个字节的位置
        Bytes.int2bytes(len, header, 12);

        buffer.writerIndex(savedWriteIndex);
        //写入完整的报文头
        buffer.writeBytes(header);
        buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
    }

    protected void encodeRequestData(Channel channel, ObjectOutput out, Object data, String version) throws IOException {
       //定义了继承方法,子类可重写该方法,通过DubboCodec重写实现
        encodeRequestData(out, data);
    }
}

public class DubboCodec extends ExchangeCodec {

    protected void encodeRequestData(Channel channel, ObjectOutput out, 
                    Object data, String version) throws IOException {
            //每一次远程调用都封装成RpcInvocation,能拿到
            RpcInvocation inv = (RpcInvocation) data;
            //写入框架版本
            out.writeUTF(version);
            String serviceName = inv.getAttachment(INTERFACE_KEY);
            if (serviceName == null) {
                serviceName = inv.getAttachment(PATH_KEY);
            }
            //写入接口服务名
            out.writeUTF(serviceName);
            //写入服务版本
            out.writeUTF(inv.getAttachment(VERSION_KEY));
            //写入调用方法名
            out.writeUTF(inv.getMethodName());
            //写入方法参数类型描述
            out.writeUTF(inv.getParameterTypesDesc());
            Object[] args = inv.getArguments();
            if (args != null) {
                //依次写入方法参数值
                for (int i = 0; i < args.length; i++) {
                    out.writeObject(encodeInvocationArgument(channel, inv, i));
                }
             }
            //写入隐式参数
            out.writeAttachments(inv.getObjectAttachments());
}

       在处理完编码请求后,可以看下响应的编码在ExchangeCodec#encodeResponse中实现,具体响应体编码在DubboCodec#encodeResponseData中实现。

protected void encodeResponse(Channel channel, ChannelBuffer buffer, Response res) throws IOException {
        int savedWriteIndex = buffer.writerIndex();
        try {
            //获取指定或默认的序列化协议(默认为Hessian2)
            Serialization serialization = getSerialization(channel);
            //构造16字节报文头
            byte[] header = new byte[HEADER_LENGTH];
            //占用2个字节存储魔数
            Bytes.short2bytes(MAGIC, header);
            //在第三个的存储响应标志
            byte status = res.getStatus();
            header[3] = status;
            //设置请求唯一标识
            Bytes.long2bytes(res.getId(), header, 4);
            //空出16字节头部用于存储响应报文
            buffer.writerIndex(savedWriteIndex + HEADER_LENGTH);

            ChannelBufferOutputStream bos = new ChannelBufferOutputStream(buffer);
            ObjectOutput out = serialization.serialize(channel.getUrl(), bos);
            if (status == Response.OK) {
                if (res.isHeartbeat()) {
                    encodeEventData(channel, out, res.getResult());
                } else {
                    //交给子类覆盖方法实现
                    encodeResponseData(channel, out, res.getResult(), res.getVersion());
                }
            } else {               
                out.writeUTF(res.getErrorMessage());
            }
            ...
            int len = bos.writtenBytes();
            //检查是否超出了80M大小限制
            checkPayload(channel, len);
            Bytes.int2bytes(len, header, 12);
            buffer.writerIndex(savedWriteIndex);
            buffer.writeBytes(header);
            buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
        } catch (Throwable t) {
            buffer.writerIndex(savedWriteIndex);
            if (!res.isEvent() && res.getStatus() != Response.BAD_RESPONSE) {
                Response r = new Response(res.getId(), res.getVersion());
                r.setStatus(Response.BAD_RESPONSE);
                if (t instanceof ExceedPayloadLimitException) {
                    try {
                        //这里告知是超出限制异常
                        r.setErrorMessage(t.getMessage());
                        channel.send(r);
                        return;
                    } catch (RemotingException e) {
                    }
                } else {
                   ...
                }
            }
            ....
        }
}


public class DubboCodec extends ExchangeCodec {
    ...
    protected void encodeResponseData(Channel channel, ObjectOutput out, Object data, String version) throws IOException {
        Result result = (Result) data;
        //判断客户端请求的版本是否支持服务端返回
        boolean attach = Version.isSupportResponseAttachment(version);

        Throwable th = result.getException();
        if (th == null) {
            //如果没有抛出异常则获取正常结果
            Object ret = result.getValue();
            if (ret == null) {
                out.writeByte(attach ? RESPONSE_NULL_VALUE_WITH_ATTACHMENTS
                : RESPONSE_NULL_VALUE);
            } else {
                out.writeByte(attach ? RESPONSE_VALUE_WITH_ATTACHMENTS 
                : RESPONSE_VALUE);
                out.writeObject(ret);
            }
        } else {
             //如果有抛出错误或异常,标记调用异常,序列化异常信息
            out.writeByte(attach ? RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS 
                : RESPONSE_WITH_EXCEPTION);
            out.writeThrowable(th);
        }
    }
    ...
}

        跟编码类似,这里也分为两部分,首先分解报文的头部(16字节),然后解码报文体携带的内容 的,以及如何将报文体的内容转换成一个RpcInvocation对象,当服务器端进行解码时,会触发ExchangeCodec#decode方法。

public class ExchangeCodec extends TelnetCodec {

    @Override
    public Object decode(Channel channel, ChannelBuffer buffer) throws IOException {
        int readable = buffer.readableBytes();
        byte[] header = new byte[Math.min(readable, HEADER_LENGTH)];
        //先读16字节的报文头
        buffer.readBytes(header);
        return decode(channel, buffer, readable, header);
    }

    @Override
    protected Object decode(Channel channel, ChannelBuffer buffer, int readable, byte[] header) throws IOException {
        //如果处理的字节流的起始处不是Dubbo魔数时
        if (readable > 0 && header[0] != MAGIC_HIGH
                || readable > 1 && header[1] != MAGIC_LOW) {
          
            int length = header.length;
            //网络流中还有可读取的数据
            if (header.length < readable) {
                header = Bytes.copyOf(header, readable);
                
                buffer.readBytes(header, length, readable - length);
            }

            for (int i = 1; i < header.length - 1; i++) {
                if (header[i] == MAGIC_HIGH && header[i + 1] == MAGIC_LOW) {
                    buffer.readerIndex(buffer.readerIndex() - header.length + i);
                    header = Bytes.copyOf(header, i);
                    break;
                }
            }
            return super.decode(channel, buffer, readable, header);
        }

        //网络流数据不够16个字节,则期待更多数据
        if (readable < HEADER_LENGTH) {
            return DecodeResult.NEED_MORE_INPUT;
        }
    
        //提取头部存储的报文长度,并校验是否超出限制
        int len = Bytes.bytes2int(header, 12);
        checkPayload(channel, len);

        //如果不是完整的Dubbo报文,则等待更多的数据
        int tt = len + HEADER_LENGTH;
        if (readable < tt) {
            return DecodeResult.NEED_MORE_INPUT;
        }

        ChannelBufferInputStream is = new ChannelBufferInputStream(buffer, len);
        try {
            //解码消息体,完整的RPC调用报文
            return decodeBody(channel, is, header);
        } finally {
             //如果解码过程发生问题,则跳过这次RPC调用报文
            if (is.available() > 0) {
                try {
                    StreamUtils.skipUnusedStream(is);
                } catch (IOException e) {
                   ...
                }
            }
        }
    }


    protected Object decodeBody(Channel channel, InputStream is, byte[] header) 
            throws IOException {
     
        byte flag = header[2], 
        proto = (byte) (flag & SERIALIZATION_MASK);
        long id = Bytes.bytes2long(header, 4);

        //如果是响应回复
        if ((flag & FLAG_REQUEST) == 0) {
            Response res = new Response(id);
            if ((flag & FLAG_EVENT) != 0) {
                res.setEvent(true);
            }
            byte status = header[3];
            res.setStatus(status);
            try {
                //进行反序列化
                ObjectInput in = CodecSupport.deserialize(channel.getUrl(), is, proto);
                if (status == Response.OK) {
                    Object data;
                    if (res.isHeartbeat()) {
                        data = decodeHeartbeatData(channel, in);
                    } else if (res.isEvent()) {
                        data = decodeEventData(channel, in);
                    } else {
                        data = decodeResponseData(channel, in, getRequestData(id));
                    }
                    res.setResult(data);
                } else {
                    res.setErrorMessage(in.readUTF());
                }
            } catch (Throwable t) {
                res.setStatus(Response.CLIENT_ERROR);
                res.setErrorMessage(StringUtils.toString(t));
            }
            return res;
        } else {
            //如果是请求
            Request req = new Request(id);
            req.setVersion(Version.getProtocolVersion());
            req.setTwoWay((flag & FLAG_TWOWAY) != 0);
            if ((flag & FLAG_EVENT) != 0) {
                req.setEvent(true);
            }
            try {
                //反序列化
                ObjectInput in = CodecSupport.deserialize(channel.getUrl(), is, proto);
                Object data;
                if (req.isHeartbeat()) {
                    data = decodeHeartbeatData(channel, in);
                } else if (req.isEvent()) {
                    data = decodeEventData(channel, in);
                } else {
                    data = decodeRequestData(channel, in);
                }
                req.setData(data);
            } catch (Throwable t) {
                req.setBroken(true);
                req.setData(t);
            }
            return req;
        }
    }
}

3.总结

       本篇主要讲解Dubbo网络通信层的实现原理,介绍了Client和Server的初始化流程,信道处理类的相关实现,线程分发策略以及线程池的实现,还讲解了Dubbo通信协议的设计以及编解码的实现原理。

参考文献

zhuanlan.zhihu.com/p/98562180 Dubbo协议详解

www.jianshu.com/p/cc7597dfe… 

www.jianshu.com/p/abfa29c01… CompetableFutrue深度解

blog.csdn.net/u010013573/… dubbo