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