做推文封面的网站,电子商务行业的发展趋势,Wordpress排版混乱,佛山技术支持 禅城企业网站grpc比http性能高的原因
二进制消息格式#xff1a;gRPC使用Protobuf#xff08;一种有效的二进制消息格式#xff09;进行序列化#xff0c;这种格式在服务器和客户端上的序列化速度非常快#xff0c;且序列化后的消息体积小#xff0c;适合带宽有限的场景。
HTTP/2协…grpc比http性能高的原因
二进制消息格式gRPC使用Protobuf一种有效的二进制消息格式进行序列化这种格式在服务器和客户端上的序列化速度非常快且序列化后的消息体积小适合带宽有限的场景。
HTTP/2协议gRPC是为HTTP/2设计的HTTP/2协议在发送和接收方面都是紧凑且高效的支持多路复用即在单个TCP连接上可以复用多个HTTP/2调用消除了应用程序层的队头阻塞问题。
流控制和双向通信gRPC支持双向流控制机制允许客户端和服务器之间进行实时的双向通信这对于需要实时数据交互的应用非常有利。
为什么protobuf比较高效
概括
即序列化后数据体积小压缩率高、序列化和反序列化速度快。
与XML、JSON这类文本协议相比ProtoBuf通过T-L-VTAG-LENGTH-VALUE方式编码不需要, {, }, :等分隔符来结构化信息。同时在编码层面使用varint压缩所以描述同样的信息protobuf序列化后的体积要小很多在网络中传输消耗的网络流量更少。
详细
1压缩率高
protobuf基于接口描述语言IDL(Interface Description Language)实现消息结构的定义传输数据的两端都需要定义该消息结构并保存在.proto文件中这样就不需要在消息数据中定义结构信息自然就把空间压榨到极限了。例如 package my; message helloworld { required int32 id 1; required string str 2; optional int32 wow 3; }
除此之外每个消息项前面有对应的tag才能解析对应的数据类型类似于计算机网络中传输IP数据包也需要分隔符来标识一样。对于protobuftag的大小是一个字节即八位tag的计算方式: tag (field_number 3) | wire_type其中上面定义的123可以类比json中的key。field_number是.proto文件用于定义某个字段比如对于上述消息结构id是1str是2wow是3wire_type是google官方定义的它是消息结构类型的一种再次分类每个wire_type都可以对应多种数据类型每种数据类型都有对应的wire_type可以观察到protobuf支持的wire_type 范围是0~5对应二进制也就是000~101正好是三位那么按照tag计算公式field_number左移三位之后再或上wire_type就组成了tag。这样就总共是六位放在一个字节中表示tag就可以标识该字段的结构信息。因此在判断wire_type类型的时候只需要取后三位。
2解析快
aVarint编码
在说varint之前我们回顾一下传输int需要四字节但如果这个数用不到四字节那么会导致浪费例如对于整数267二进制表示是00000000 00000000 00000001 00001011前两个字节就是浪费的。
varint是一种特殊的编码例如下图是两个字节(这两个字节其实对于varint编码来说表示267why我们后面就见分晓) 第一个字节最高是1表示下一个字节也是其想表述的数据的组成部分。反之0则表示下一个字节与当前字节没有关系。
这样的话其实上面16位里只有14位是有实际数据意义的从左到右先放高位那么就是0000010 0001011连一起就是00000100001011,正好就是前面我们的例子267的二进制表示
那么varint编码有什么问题吗
如果想表示-1二进制是11111111 11111111 11111111 11111111 用varint编码效率很低。
bZigzag编码
Zigzag编码规则如下
如果数据是负数那么套用2*|x|-1来编码表示 如果数据是正数那么套用2*|x| 来编码表示 那么对于-1就编成1再二进制表示就是00000001
上面的编码都是基于数字编码那么如果传输字符串就显得不太方便。
cTLVTag-Length-Value
这不是一种编码格式而是一种传输规则对于传输字符串Tag还是起到分隔符的作用Length表示字符串的长度Value表示字符的具体值不进行编码。