ProtoBuf在java中的实际应⽤
在实际的应⽤之前,我们再了解以下protobuf。
通过⽐较它与其他数据格式进⾏⽐较,可以使我们更好的认识它的应⽤场景。下⾯与XML,JSON进⾏⼀个简单的⽐较。
JSON:⼀般在web项⽬中⼴泛使⽤,主要是由于浏览器的⽀持⾮常好,内部构建了与多函数来⽀持JSON。具有可读性。
XML:在WebService中⼴泛使⽤,但是过于冗余(毕竟是通过标签进⾏标识)。也具有可读性。
ProtoBuf:适合⾼性能,对响应速度有要求的数据传输场景。由于是⼆进制数据格式需要编码和解码。不具有可读性。在官⽹上描述ProtoBuf⽐XML⼩3到10倍,快20到100倍。
结论: 在⼀个需要⼤量的数据传输的场景中,如果数据量很⼤,那么选择protobuf可以明显的减少数据量,减少⽹络IO,从⽽减少⽹络传输所消耗的时间。
在上⾯我们对ProtoBuf与其他数据格式做了⽐较,只简单的了解到它的⼩和快,可这是如何实现的呢?那么我们在下⾯对ProtoBuf存储原理做⼀个简要的介绍。以下内容转载⾃博⽂-google protobuf存储原理及⼀些底层api应⽤
核⼼是Google 提出了“Base 128 Varints”编码,这是⼀种变字节长度的编码,官⽅描述为:varints是⽤⼀个或多个字节序列化整形的⼀种⽅法。
序列化⽅式
protobuf 把 message通过⼀系列key_value对来表⽰。
Key 的算法为:(field_number << 3)| wired_type
这⾥field_number 就是具体的索引,wired_type的值按下表查询。
wired_type.proto类型
0Varint int32, int64, uint32, uint64, sint32, sint64, bool, enum
164-bit fixed64, sfixed64, double
javabean是干嘛的2Length-delimited string, bytes, embedded messages, packed repeated fields
532-bit fixed32, sfixed32, float
对于int,bool,enum类型,value就是Varint。
⽽对于string,bytes,message等等类型,value是长度+原始内容编码。
举例int类型存储(Varint存储原理)
存储⼀个int32 类型的数字,通常是4个字节。但是Varints最少只需要⼀个字节就可以了。
Varints规定⼩于128的数字都可以⽤⼀个字节来表⽰,⽐如10, 它就会⽤⼀个字节 0000 1010 来存储。
对于⼤于128的数字,则⽤更多个字节存储。
以150举例:protobuf的存储字节是 1001 0110 0000 0001。
为什么会这样标识呢?⾸先我们了解⼀个字节共8位,表⽰的数字是255,但是Varints只⽤⼀个字节表⽰⼩于128的数字,换句话说,就是Varints只⽤了8位中的7位来表⽰数字,⽽还有⼀位被⽤来⼲嘛了呢?
Varints在官⽅规定中表⽰,每个字节的最⾼位是有特殊含义,当最⾼位为1的时候,代表后续的字节也是该数字的⼀部分,后续为0的时候,则表⽰结束。
⽐如过150,⼆进制表⽰为 1001 0110。
先取后七位 001 0110, 作为第⼀个字节的内容。
再取余下的位,补0凑齐7位,就是000 0001。
对于intel机器,是⼩端字节序,低字节位于地址低的。0010110 是低字节地址,因此排在前⾯,因为后⾯的也是数字的⼀部分,所以⾼位补1,也就成了10010110。 同样的,⾼字节000 0001,排在后⾯,并且它后⾯没有后续字节了,所以补0,也就成了 0000 0001。
因此150 在protobuf中的表⽰⽅式为 1001 0110 0000 0001。
和protobuf util的⽀持。
上⾯可以应⽤于⾃定义的bean主要⽤于web前后台的交互,同时通过JSON转换也可以进⾏与其他服务的交互,数据可以放在redis中。当然还有其他的转换⽅式,如我上⾯所说:反射,和复制属性。
反射可以通过属性名称⼀⼀对应进⾏转换,在特定的情况下也是可以通过属性类型进⾏转换。
复制属性,可以通过Spring的pyProperties(Object source, Object target)⽅法进⾏转换的。
后期我将补充此转换⽅式的案例。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论