rocketMQ 使用 netty 通信,端对端的通信,为了避免粘包、分包,需要指定发送数据的边界。

使用的解码器是 LengthFieldBasedFrameDecoder

// org.apache.rocketmq.remoting.protocol.RemotingCommand#encode
public ByteBuffer encode() {
    // 1> header length size
    int length = 4;

    // 2> header data length
    byte[] headerData = this.headerEncode();
    length += headerData.length;

    // 3> body data length
    if (this.body != null) {
        length += body.length;
    }

    ByteBuffer result = ByteBuffer.allocate(4 + length);

    // length
    result.putInt(length);

    // header length
    result.put(markProtocolType(headerData.length, serializeTypeCurrentRPC));

    // header data
    result.put(headerData);

    // body data;
    if (this.body != null) {
        result.put(this.body);
    }

    result.flip();

    return result;
}

从中可以看出数据的格式:4, 4, headerData, bodyData

4 字节存储数据的总长度

4 字节存储头的长度和元数据

headerData 存储头数据

bodyData 存储内容

 

RocketMQ 使用的解码器:

public class NettyDecoder extends LengthFieldBasedFrameDecoder {
    private static final InternalLogger log = InternalLoggerFactory.getLogger(RemotingHelper.ROCKETMQ_REMOTING);

    private static final int FRAME_MAX_LENGTH =
        Integer.parseInt(System.getProperty("com.rocketmq.remoting.frameMaxLength", "16777216"));

    public NettyDecoder() {
        super(FRAME_MAX_LENGTH, 0, 4, 0, 4);
    }
}

posted on 2019-10-19 12:24  偶尔发呆  阅读(1055)  评论(0编辑  收藏  举报