本文主要是介绍protobuf的困局,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
很早以前就跟踪过protobuf,由于一直做业务系统,感觉protobuf在扩展性方面有问题,面对多变的业务逻辑,缺乏灵活性。目前,公司强行推行protobuf作为消息格式,除了吐槽之外,只能再次深入研究下protobuf的机制,希望能够找到一个突破点。
目前,protobuf有几个重要特性,
1、基于7bit格式的可变编码。默认状态下,对浮点数,负数没有编码优势,需要特别指定sint之类。
2、允许指定每个字段的fid。这个特性,使得protobuf比C结构模式有更大的灵活性,可以不传字段也能正确解析。这个属性应该是后面才加上的,在我印象中,早期版本是没有的。
3、基于proto文件的编解码器。这个模式有好处,可以跨语言使用,而且宿主语言直接可以以类的方式来访问。但由于是源码级兼容,并且编解码器是硬编码的,当proto发生变化时,所有引用该文件的程序都要重新编译。
4、类型和fid是混合编码,至少减少一个字节用于存储类型。由于历史原因,只有3个bit用于表示类型,而且由于历史原因,有几个值被废弃,可供选择的范围更小。
从传输内容来看,他的格式为FID + TYPE + BUFFER。
1、由于FID是可变编码,具有灵活性。
2、BUFFER是二进制内容,本身没有格式,所以无所谓局限性。但由于BUFFER是根据TYPE来解析的,所以他也会被TYPE所限制。
3、TYPE由于3bit的限制,并且google内部大量已经存在的资源,TYPE被改变的可能性很小,并且也没有可以改变的空间。
通过上面的分析,我们可以看到,在protobuf现在版本中,能扩的地方都扩,而不能扩的地方就剩下TYPE这个字段。这个就是我所要表述的protobuf困局的核心内容,而且是先天缺陷。
为什么这么说呢?我们看到,protobuf在表述整型、浮点等基础类型方面,有够用的表达力【注意,不是足够的表达力】,但在表述list/嵌套/raw等复合类型时,只能靠proto来显式指定。也就是说,在这种情况下,如果没有或者缺乏最新proto文件,你将手足无措。
如果有人说,这是protobuf的优势,我将深度鄙视。proto的解析器,一大段一大段代码,都在还这个债。
protobuf解析器的速度,来源于他硬编码的解析程序,得到接近于直接内存转换的速度,这是个优势。但TYPE的缺失,将限制protobuf更广泛的引用,特别是在业务多变的系统中。
有人会差异于为何没有提到掩码。由于掩码只在本地存在,所以无关紧要,即使出现问题,也容易被修正。还有字段描述和反射是他的优势,也不赘述了。
另附上一个名人的吐槽:Protocol Buffers for C
这篇关于protobuf的困局的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!