参考文章:https://worktile.com/tech/share/prototol-buffers

是Google开发一种数据描述语言,能够将结构化数据序列化,可用于数据存储、通信协议等方面。据Google官方文档介绍,现在Google内部已经有48,162个消息类型定义在12,183个proto文件中。本文会从快速入门、语言规范、编码协议、性能评估等几个方面对Prototol Buffers进行介绍。

不了解Protocol Buffers的同学可以把它理解为更快、更简单、更小的JSON或者XML,区别在于Protocol Buffers是二进制格式,而JSON和XML是文本格式。


相对于XML,Protocol Buffers的具有如下几个优点:

  • 简洁
  • 体积小:消息大小只需要XML的1/10 ~ 1/3
  • 速度快:解析速度比XML快20 ~ 100倍
  • 使用Protocol Buffers的编译器,可以生成更容易在编程中使用的数据访问代码
  • 更好的兼容性,Protocol Buffers设计的一个原则就是要能够很好的支持向下或向上兼容。


看一个简单的对比例子,表达一个用户的三个基本的属性,如果使用XML消息体大小为82 bytes。

如果使用JSON消息体大小为56 bytes。

使用Protocol Buffers咋则只需要 31 bytes,看到这些二进制数据大家可以暂时忽略,后面会具体分析这些二进制数据是如何编码的。

接下来先看一个简单的入门示例,在该例子中我们从准备环境开始,编写proto文件,到最后使用Protocol Buffers编译器生成代码,再到具体的使用。

从https://github.com/google/protobuf下载编译安装protoc,并下载Protobuf SDK。

开始编写proto文件,使用message关键字定义消息类型,消息中每个字段需要指定字段类型和字段序号。同一个message中字段

使用protoc命令生成代码,使用--cpp_out、--java_out、--python_out命令选项可以生成C++、Java、Python代码,在最新版本Protocol Buffers v3中还加入了ruby语言的支持。

生成代码的代码可以直接加入到自己的代码工程中使用,以C++语言为例:

这是一段Java语言的使用示例:

接下来会详细说明如何定义proto文件:

在消息定义中,我们需要确定三个问题:

  • 确定消息命名,给消息取一个有意义的名字。
  • 指定字段的类型
  • 定义字段的编号,在Protocol Buffers中,字段的编号非常重要,字段名仅仅是作为参考和生成代码用。需要注意的是字段的编号区间范围,其中19000 ~ 19999被Protocol Buffers作为保留字段。


    字段约束,required指定该字段必须赋值,禁止为空(在v3中该约束被移除);optional指定字段为可选字段,可以为空,对于optional字段还可以使用[default]指定默认值,如果没有指定,则会使用字段类型的默认值;使用repeated指定字段为集合。

    在一个proto文件中可以同时定义多个message类型,生成代码时根据生成代码的目标语言不同,处理的方式不太一样,如Java会针对每个message类型生成一个.java文件。还可以使用C++风格的注释。

    在Protocol Buffers中提供了很多的标量类型,供我们在定义字段类型时使用。

    可以指定字段的类型为其他message类型,如图中的示例代码所示:

    还可以使用import关键字导入其他proto文件,这有利于你进行自己的proto文件的规划和整理。

    在proto文件中消息的类型还可以嵌套,如你定义的message类型仅作为另外一个Message的字段类型。

    为了便于扩展,在proto文件中可以使用extensions关键字预留一部分字段编号出来,以便于后期给第三方扩展时使用。

    oneof关键字指定一组字段中,至少要有一个字段必须赋值。如在用户登录系统中,使用邮箱和用户名都可以登录该系统,所以通常会要求至少提供用户名或者邮箱。

    在这一部分总我们会仔细分析,Protocol Buffers序列化后的二进制代码的编码协议,不知道这些并不会影响我们使用Protocol Buffers,但是了解之后有助于我们更好的使用Protocol Buffers和进行调试。

    先从一个简单的例子开始,如图中的代码所示,我们有这样一个消息定义,在使用中给a赋值为150,最终编码得到的结果是 08 96 01,为什么编码的结果是这样,其中08又代表什么?后续一一为你介绍。

    在Protocol Buffers中采用Base-128变长编码,所谓变长编码是和定长编码相对的,定长编码使用固定字节数来表示,如int32类型的数字固定使用4 bytes表示,而变长编码是需要几个字节就使用几个字节,如对于int32类型的数字1来说,只需要1 bytes足够。Base-128变长编码的原则就两条:

  • 每个字节使用使用低7位表示数字,除了最后一个字节,其他字节的最高位都设置为1。

  • 采用Little-Endian字节序


一个Protocol Buffers的消息包含一系列字段key/value,每个字段由一个变长32位整数作为字段头,后面跟随字段体。字段头的格式如下:

(field_number << 3) | wire_type-field_number:    字段序号
-wire_type:    字段编码类型


这里是详细的字段说明,其中3、4已经放弃:


接下来我们对Protocol Buffers的性能做一些测试。

在测试过程中,我们使用一个统一的消息体格式,主要评估以下两个性能指标:

  • 序列化速度
  • 报文大小


尽管Protocol Buffers有序列化速度快、报文体积小以及更好的兼容性等优点,但同时也有一些缺点,在使用时要根据实际情况来选择使用。

  • 缺乏自描述,可读性差,可以使用TextFormat
  • 适用于内部服务和存储,而不适合直接对外公开,如Open API,protobuf v3将加入对json的支持,可解决此问题


与Protocol Buffers类似的框架有微软出的Bond和Facebook出的Thrift,感兴趣的同学可以去下载研究一下。

转载于:https://www.cnblogs.com/liugh/articles/6804380.html

Protocol Buffer序列化协议及应用相关推荐

  1. 架构师之路 — 分布式系统 — Protocol Buffers 序列化协议

    目录 文章目录 目录 Protocol Buffers 序列化协议 定义数据结构 序列化传输 Protocol Buffers 序列化协议 Protocol Buffers 是一种高性能的.语言无关的 ...

  2. 知心王姐小饭桌 IM消息应用开发:一看看懂Protocol Buffer(协议篇)

    前言 由于笔者业团队的业务对即时通讯服务有很大的依赖,春节结束后的第一天,红包没到,产品同学先到了,产品同学和我说要做一款IM,看到需求文档后和设计图后笔者大吃一斤 这不就是一个翻版的web qq吗? ...

  3. Protocol Buffer 序列化

    Protobuf使用 目录 proto3的更新 定义协议格式 编译protobuf protobuf_API 枚举和嵌套类 标准消息方法 解析和序列化 写一条消息 阅读消息 编译 Protobuf扩展 ...

  4. 不仅仅于 Json和XML ,快来学习Google出品的序列化神器Protocol Buffer

    前言 习惯用 Json.XML 数据存储格式的你们,相信大多都没听过Protocol Buffer Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存 ...

  5. js中应用protocol buffer

    前段时间公司项目需要用到protocol buffer数据传输协议,这是什么东西,根本没接触过,好好的json干嘛不用?怀着好奇心去了解学习,最后顺利运用.下面是一些是经验,希望能帮到一些人. 首先我 ...

  6. 线程与进程,http、https(post、get),socket(tcp、udp)的拆包和粘包,protocol buffer、大头小头简述

    一.tcp和udp区别? 三次握手安全:tcp建立连接(三次握手),安全可靠(有序,无差错.无丢失.无重复): 建立连接:udp通信前不需建立连接,不可靠传输(视频.音频通话): 分组开销:TCP面向 ...

  7. linux下用google protocol buffer(gpb)出现的编译问题------前后耗掉1个多小时

    平常没有用google protocol buffer(gpb)协议, 而是用的公司的私有化序列化工具. 最近刚好要用这个gpb, 于是搞了一把. 在工程中看了一下, 之前是有对应的gpb基础库的, ...

  8. Tensorflow中的Protocol Buffer

    Protocol Buffer是谷歌公司开发的处理结构化数据的工具.注意这里介绍的结构化数据和大数据中的结构化数据的概念不同,这里的结构化数据指的是拥有多种属性的数据.比如一个用户:包含名字,ID,和 ...

  9. Canal与Kafka数据传输协议protocol buffer

    1.写在前面 实时数仓开发中,利用Canal伪装slave获取MySQL的增量数据,获取后的数据由Kafka生产者接收,交由Flink实时流计算.传输数据量较大时,会占用内存及带宽,所以考虑将数据序列 ...

最新文章

  1. Bitcoin Unlimited客户端发布新版本,删除了BSV协议功能
  2. Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
  3. python 除法取整_Python中整数和浮点数
  4. c语言静态图片做成动态效果,如何使静态图片做成动态效果?怎么让静态图片动起来...
  5. VTK:小部件之ImageTracerWidget
  6. vue中的dom基本渲染
  7. CRM Fiori launchpad请求响应结果的字段分析
  8. 数据库ACID、脏读、不可重复读和幻读
  9. 循环在c语言中的表示什么作用,《C语言中的for循环》教案
  10. 360浏览器升级_社畜必备!360浏览器上线“文档”功能 一键开启云办公
  11. mysql hash索引_mysql hash索引
  12. 【windows】修复win7便签
  13. 奶粉php小蛋白易消化,揭开“小分子”奶粉真面目:真值得买还是瞎忽悠?
  14. 用批处理的方式解压文件
  15. D11:Chickens and Rabbits(鸡兔同笼问题,附题解)
  16. single-precision operand implicitly
  17. SQL脚本得到Epicor客制化信息
  18. fastboot 命令
  19. HNU-电子测试平台与工具-数字密码锁实验报告
  20. 计算机音乐如何复制到手机桌面,电脑上的歌怎么传到手机上

热门文章

  1. 更改Webshpere的profile端口及删除profile
  2. 多线程Java服务器简单实现
  3. CentOS 6.2 yum安装配置lnmp服务器(Nginx+PHP+MySQL)
  4. Mc神秘·音乐-舞曲网
  5. vs2010中添加项目中找不到EntityFramework实体框架解决办法
  6. 建立asp.net应用程序提示:无法与服务器建立连接
  7. linux 找回gpt分区,linux – 修复graid mini磁盘上损坏的GPT分区
  8. 9个点的所有解锁图_黔隆科技刷机教程酷派C1068忘记密码刷机解锁降级救砖解屏幕锁账户锁教程...
  9. ADS与RealView MDK
  10. 时间被空间和运动度量