ProtoBuf 作为一种跨平台、语言无关、可扩展的序列化结构数据的方法,已广泛应用于网络数据交换及存储。随着互联网的发展,系统的异构性会愈发突出,跨语言的需求会愈加明显,同时 gRPC 也大有取代Restful之势,而 ProtoBuf 作为g RPC 跨语言、高性能的法宝,我们技术人有必要
深入理解 ProtoBuf 原理,为以后的技术更新和选型打下基础。
我将过去的学习过程以及实践经验,总结成系列文章,与大家一起探讨学习,希望大家能有所收获,当然其中有不正确的地方也欢迎大家批评指正。
本系列文章主要包含:
- 深入理解 ProtoBuf 原理与工程实践(概述)
- 深入理解 ProtoBuf 原理与工程实践(编码)
- 深入理解 ProtoBuf 原理与工程实践(序列化)
- 深入理解 ProtoBuf 原理与工程实践(工程实践)
一、什么是ProtoBuf
ProtoBuf(Protocol Buffers)是一种跨平台、语言无关、可扩展的序列化结构数据的方法,可用于网络数据交换及存储。
在序列化结构化数据的机制中,ProtoBuf是灵活、高效、自动化的,相对常见的XML、JSON,描述同样的信息,ProtoBuf序列化后数据量更小、序列化/反序列化速度更快、更简单。
一旦定义了要处理的数据的数据结构之后,就可以利用ProtoBuf的代码生成工具生成相关的代码。只需使用 Protobuf 对数据结构进行一次描述,即可利用各种不同语言(proto3支持C++, Java, Python, Go, Ruby, Objective-C, C#)或从各种不同流中对你的结构化数据轻松读写。
二、为什么是 ProtoBuf
大家可能会觉得 Google 发明 ProtoBuf 是为了解决序列化速度的,其实真实的原因并不是这样的。
ProtoBuf最先开始是 Google用来解决索引服务器 request/response 协议的。没有ProtoBuf之前,Google 已经存在了一种 request/response 格式,用于手动处理 request/response 的编解码。它也能支持多版本协议,不过代码不够优雅:
if (protocolVersion=1) {
doSomething();
} else if (protocolVersion=2) {
doOtherThing();
} ...
如果是非常明确的格式化协议,会使新协议变得非常复杂。因为开发人员必须确保请求发起者与处理请求的实际服务器之间的所有服务器都能理解新协议,然后才能切换开关以开始使用新协议。
这也就是每个服务器开发人员都遇到过的低版本兼容、新旧协议兼容相关的问题。
为了解决这些问题,于是ProtoBuf就诞生了。
ProtoBuf 最初被寄予以下 2 个特点:
- 更容易引入新的字段,并且不需要检查数据的中间服务器可以简单地解析并传递数据,而无需了解所有字段。
- 数据格式更加具有自我描述性,可以用各种语言来处理(C++, Java 等各种语言)。
这个版本的 ProtoBuf 仍需要自己手写解析的代码。
不过随着系统慢慢发展,演进,ProtoBuf具有了更多的特性: