美文网首页
dubbo协议报文消息格式

dubbo协议报文消息格式

作者: 南宋临安府 | 来源:发表于2018-03-08 22:39 被阅读0次

    “谷神不死,是谓玄牝。
    玄牝之门,是谓天地根。
    绵绵若存,用之不勤。”[1]

    dubbo默认采用netty进行网络传输,协议中对字节流的处理在com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec类中,包含了对request请求的编码和解码,response响应的编码和解码。
    dubbo协议采用固定长度的消息头(16字节)和不定长度的消息体来进行数据传输,消息头定义了netty在IO线程处理时需要的信息,协议的报文格式如下:


    dubbo_message_protocol_header

    消息头详解

    协议头是16字节的定长数据:

    2byte magic:类似java字节码文件里的魔数,用来判断是不是dubbo协议的数据包。魔数是常量0xdabb
    1byte 的消息标志位:16-20序列id,21 event,22 two way,23请求或响应标识
    1byte 状态,当消息类型为响应时,设置响应状态。24-31位。状态位, 设置请求响应状态,dubbo定义了一些响应的类型。具体类型见com.alibaba.dubbo.remoting.exchange.Response
    8byte 消息ID,long类型,32-95位。每一个请求的唯一识别id(由于采用异步通讯的方式,用来把请求request和返回的response对应上)
    4byte 消息长度,96-127位。消息体 body 长度, int 类型,即记录Body Content有多少个字节。
    

    解码过程 ExchangeCodec->encode-> encodeRequest

    public void encode(Channel channel, ChannelBuffer buffer, Object 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);
            // header.
            byte[] header = new byte[HEADER_LENGTH];
            // set magic number.
            Bytes.short2bytes(MAGIC, header);
    
            // set request and serialization flag.
            header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId());
    
            if (req.isTwoWay()) header[2] |= FLAG_TWOWAY;
            if (req.isEvent()) header[2] |= FLAG_EVENT;
    
            // set request id.
            Bytes.long2bytes(req.getId(), header, 4);
    
            // encode request data.
            int savedWriteIndex = buffer.writerIndex();
            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());
            }
            out.flushBuffer();
            if (out instanceof Cleanable) {
                ((Cleanable) out).cleanup();
            }
            bos.flush();
            bos.close();
            int len = bos.writtenBytes();
            checkPayload(channel, len);
            Bytes.int2bytes(len, header, 12);
    
            // write
            buffer.writerIndex(savedWriteIndex);
            buffer.writeBytes(header); // write header.
            buffer.writerIndex(savedWriteIndex + HEADER_LENGTH + len);
        }
    

    消息体详解

    实现源码在DubboCodec.encodeRequestData(Channel channel, ObjectOutput out, Object data):

       protected void encodeRequestData(Channel channel, ObjectOutput out, Object data) throws IOException {
           RpcInvocation inv = (RpcInvocation) data;
    
           out.writeUTF(inv.getAttachment(Constants.DUBBO_VERSION_KEY, DUBBO_VERSION));
           out.writeUTF(inv.getAttachment(Constants.PATH_KEY));
           out.writeUTF(inv.getAttachment(Constants.VERSION_KEY));
    
           out.writeUTF(inv.getMethodName());
           out.writeUTF(ReflectUtils.getDesc(inv.getParameterTypes()));
           Object[] args = inv.getArguments();
           if (args != null)
               for (int i = 0; i < args.length; i++) {
                   out.writeObject(encodeInvocationArgument(channel, inv, i));
               }
           out.writeObject(inv.getAttachments());
       }
    

    消息体的内容如下:
    1、dubbo版本号
    2、invoke的路径
    3、invoke的provider端暴露的服务的版本号
    4、调用的方法名称
    5、参数类型描述符
    6、遍历请求参数值并编码
    7、dubbo请求的attachments


    1. 老子《道德经》第六章,老子故里,中国鹿邑。

    相关文章

      网友评论

          本文标题:dubbo协议报文消息格式

          本文链接:https://www.haomeiwen.com/subject/qddufftx.html