1 Dubbo协议概述
Dubbo协议是建立在TCP(传输层协议)之上的一种应用程序协议。它参考了TCP协议栈中的协议,协议内容由header和body两部分组成。
2 协议头header的组成
协议头组成如下所示。
header格式 | ||||||
bit序号 | 0-7 | 8-15 | 16-23 | 24-31 | 32-95 | 96-127 |
字节数 | 1 | 1 | 1 | 1 | 8 | 4 |
内容 | magic hight | magic low | request flag and serialization id | response status | request id | body length |
由上可知,协议头总共包含了16个字节的数据。具体内容如下所述。
2.1 魔数
前2个字节为魔数。这里用来标识一个帧的开始,固定为0xdabb。第一个字节固定为0xda,第二个字节固定为0xbb。
// header length.
protected static final int HEADER_LENGTH = 16;
// magic header.
protected static final short MAGIC = (short) 0xdabb;
protected static final byte MAGIC_HIGH = Bytes.short2bytes(MAGIC)[0];
protected static final byte MAGIC_LOW = Bytes.short2bytes(MAGIC)[1];
2.2 请求类型和序列化类型ID
第3个字节是请求类型和序列化类型ID的组合结果(进行两者的 |(按位或)运算)。
// set request and serialization flag.
header[2] = (byte) (FLAG_REQUEST | serialization.getContentTypeId());
(1)高3位标示请求类型,其枚举值如下所示。
protected static final byte FLAG_REQUEST = (byte) 0x80; //10000000 (100)
protected static final byte FLAG_TWOWAY = (byte) 0x40; //01000000 (010)
protected static final byte FLAG_EVENT = (byte) 0x20; //00100000 (001)
(2)低5位标示序列化方式,其枚举值如下所示。
/**
* 序列化类型ID (用5个比特来存储该值)
*/
// org.apache.dubbo.common.serialize.Constants
public interface Constants {
byte HESSIAN2_SERIALIZATION_ID = 2; // 0010 (00010)
/**
* JavaSerialization 的 序列化类型ID
*/
byte JAVA_SERIALIZATION_ID = 3; // 0011 (00011)
byte COMPACTED_JAVA_SERIALIZATION_ID = 4;
byte FASTJSON_SERIALIZATION_ID = 6;
byte NATIVE_JAVA_SERIALIZATION_ID = 7;
byte KRYO_SERIALIZATION_ID = 8;
byte FST_SERIALIZATION_ID = 9;
byte NATIVE_HESSIAN_SERIALIZATION_ID = 10;
byte PROTOSTUFF_SERIALIZATION_ID = 12;
byte AVRO_SERIALIZATION_ID = 11;
byte GSON_SERIALIZATION_ID = 16;
byte PROTOBUF_JSON_SERIALIZATION_ID = 21;
byte PROTOBUF_SERIALIZATION_ID = 22;
byte FASTJSON2_SERIALIZATION_ID = 23;
byte KRYO_SERIALIZATION2_ID = 25;
/**
* 最大不超过31,因为只有5个比特用于存储序列化类型ID
*/
byte CUSTOM_MESSAGE_PACK_ID = 31; // 11111 (11111)
}
2.3 响应结果码
第4个字节用于标识响应结果码。此值只在响应报文里设置(在请求报文里不设置)。响应结果码有以下几种。
// org.apache.dubbo.remoting.exchange.Response
public class Response {
/**
* ok.
*/
public static final byte OK = 20;
/**
* serialization error
*/
public static final byte SERIALIZATION_ERROR = 25;
/**
* client side timeout.
*/
public static final byte CLIENT_TIMEOUT = 30;
/**
* server side timeout.
*/
public static final byte SERVER_TIMEOUT = 31;
/**
* channel inactive, directly return the unfinished requests.
*/
public static final byte CHANNEL_INACTIVE = 35;
/**
* request format error.
*/
public static final byte BAD_REQUEST = 40;
/**
* response format error.
*/
public static final byte BAD_RESPONSE = 50;
/**
* service not found.
*/
public static final byte SERVICE_NOT_FOUND = 60;
/**
* service error.
*/
public static final byte SERVICE_ERROR = 70;
/**
* internal server error.
*/
public static final byte SERVER_ERROR = 80;
/**
* internal server error.
*/
public static final byte CLIENT_ERROR = 90;
/**
* server side threadpool exhausted and quick return.
*/
public static final byte SERVER_THREADPOOL_EXHAUSTED_ERROR = 100;
//...
}
2.4 请求ID
之后的8个字节是标识请求ID,用于唯一标识一个请求。
2.5 body内容的大小
最后的4个字节标识body内容的大小(最大约4G),用于指定在协议头header内容之后的多少个字节是协议body的内容。