tRPC-Go 中的 codec
模块的 FrameHead
的 construct
方法实现了 tRPC 协议栈的构建过程:
// construct 构造整个帧的二进制数据
func (h *FrameHead) construct(header, body []byte) ([]byte, error) {
headerLen := len(header)
if headerLen > math.MaxUint16 {
return nil, errHeadOverflowsUint16
}
// ... 忽略具体代码
return buf, nil
}
图形化,则整个帧的结构设计为:
其中:
- 2 字节魔数:固定为 2352。一般自定义协议中会用到魔数,常见也都是 2 个字节:用于快速识别字节流是否是程序能够处理的,能处理才进行后面的 耗时 业务操作,如果不能处理,尽快执行失败,断开连接等操作。
- 2 字节头部长度:限制了协议的请求头不能超过 64KB,所以使用中,如果有大量透传字段的业务场景,需要注意这个限制。tRPC 协议头部的格式使用 pb 定义,对应生成的 golang 结构体为
trpc.RequestProtocol
; - 4 字节帧的总长度: 源码中默认的最大长度为
codec.DefaultMaxFrameSize = 10*1024*1024
,即 10MB,但是因为是公开访问的变量,应用可以把这个数值改大,以支持大小超过 10MB 的帧,但是估计实际中,没有多少业务会有这个需要。另外虽然可以调大DefaultMaxFrameSize
的值,但是也不能突破 32 位长度,亦即 4GB,相信这种可能性几乎没有。
参考资料
- 自定义协议中魔数的作用