protobuf中文教程(第一篇)

声明:本文大部分内容翻译自官方英文文档,其中可能穿插着加入自己的语言用以辅助理解,本文禁止转载。

一、什么是protocol buffers

Protocol buffers是一个灵活的、高效的、自动化的用于对结构化数据进行序列化的协议,与XML相比,Protocol buffers序列化后的码流更小、速度更快、操作更简单。你只需要将要被序列化的数据结构定义一次(译注:使用.proto文件定义),便可以使用特别生成的源代码(译注:使用protobuf提供的生成工具)轻松的使用不同的数据流完成对这些结构数据的读写操作,即使你使用不同的语言(译注:protobuf的跨语言支持特性)。你甚至可以更新你的数据结构的定义(译注:就是更新.proto文件内容)而不会破坏依赖“老”格式编译出来的程序。

二、protocol buffers的工作流程

首先,你需要通过在.proto文件中定义protocol buffer的message类型来指定你想要序列化的数据结构,每一个protocol buffer message是一个逻辑上的信息记录,它包含一系列的键值对。这里展示一个最基本的.ptoto文件的例子,它定义了一个包含Person信息的message:

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }
  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }
  repeated PhoneNumber phone = 4;
}

正如你所看见的那样,message的格式非常简单--每一个message类型都有一个或多个带有唯一编号的字段,每一个字段有一个字段名和一个字段类型,字段类型可以是数值类型(比如整形或浮点型)、booleans(布尔类型)、strings(字符串类型)、raw bytes、甚至(正如上面的例子)还可以是其他的protocol buffer message类型,这允许你可以分层次的组织你的数据结构。你可以单独指定每一个字段为optional fields(可选字段)、required fields(必须字段)、repeated fields(可重复字段)。下一篇博文将会对.proto文件进行更详细的描述。

一旦定义了你的message,你就可以根据你所使用的语言(译注:如JAVA、C++、Python等)使用protocol buffer提供的编译工具编译.proto文件生成数据访问类。这些类为每一个字段都提供了简单的访问器(比如name()和set_name()),同时还提供了将整个结构化数据序列化为原始字节数据以及从原始字节数据反序列化为结构化数据的方法(译注:C++中称之为函数)。例如,如果你使用的语言是C++,运行编译器编译上述的例子将生成一个名为Person的类,在你的应用程序中你可以使用这个类来填充、序列化和反序列化Person protocol buffer messages。之后你可能会写下如下类似的代码(译注:序列化):

1 Person person;
2 person.set_name("John Doe");
3 person.set_id(1234);
4 person.set_email("[email protected]");
5 fstream output("myfile", ios::out | ios::binary);
6 person.SerializeToOstream(&output);

之后,你可以将你的message读回(译注:反序列化):

1 fstream input("myfile", ios::in | ios::binary);
2 Person person;
3 person.ParseFromIstream(&input);
4 cout << "Name: " << person.name() << endl;
5 cout << "E-mail: " << person.email() << endl;

你可以向你的message中添加新的字段而不会破坏前向兼容性;在解析时旧的二进制文件会简单的忽略掉新字段,所以,如果你的通信协议中使用protocol buffers作为数据交换格式,那么你可以扩展你的协议而不用担心会打乱现有的代码。

三、为什么不使用XML?

相对于XML,protocol buffers在序列化结构数据时拥有许多先进的特性:

1、更简单

2、序列化后字节占用空间比XML少3-10倍

3、序列化的时间效率比XML快20-100倍

4、具有更少的歧义性

5、自动生成数据访问类方便应用程序的使用

举个例子,如果你想描述一个具有name和email的person数据结构,在XML中,你需要这样做:

 <person>
    <name>John Doe</name>
    <email>[email protected]</email>
 </person>

然而,在protocol buffers的message中(protocol buffers的文本格式)你需要这样做:

# Textual representation of a protocol buffer.
# This is *not* the binary format used on the wire.
person {
  name: "John Doe"
  email: "[email protected]"
}

当这个message被编码成protocol buffer的二进制格式(上述的文本格式只是为了方便阅读、调试和编辑),它将可能占用28个字节长度并且仅需要100-200纳秒的解析时间。相比,XML版本的则至少需要占用69字节的空间(这是在移除XML中的空格、换行之后),同时,将耗费大约5000-10000纳秒的解析时间。

除此之外,手动操作protocol buffer更为方便,例如如下C++代码:

1  cout << "Name: " << person.name() << endl;
2  cout << "E-mail: " << person.email() << endl;

然而如果你使用XML,那么你将需要这样做:

1 cout << "Name: "<< person.getElementsByTagName("name")->item(0)->innerText()<< endl;
2 cout << "E-mail: "<< person.getElementsByTagName("email")->item(0)->innerText()<< endl;

事物总有两面性,和XML相比protocol buffers并不总是更好的选择,例如,protocol buffers并不适合用来描述一个基于文本的标记型文档(比如HTML),因为你无法轻易的交错文本的结构。另外,XML具有很好的可读性和可编辑性;而protocol buffers,至少在它们的原生形式上并不具备这个特点。XML同时也是可扩展、自描述的。而一个protocol buffer只有在具有message 定义(在.proto文件中定义)时才会有意义。

四、如何开始使用protocol buffers?

首先,可以在这里下载安装包或者源码包

https://developers.google.com/protocol-buffers/docs/downloads#release-packages

这包含了针对JAVA、Python和C++编译器的完整源码,同时包含了你所需要的I/O和测试类。为了完成编译和安装,请参照README文件。

一旦你完成了编译和安装,那么就可以开始使用protocol buffers了,后续的博文将会对C++和JAVA语言的具体使用细节进行阐述。

五、proto3介绍

我们最新的版本version 3 alpha release引进了一个新的语言版本--Protocol Buffers version 3 (称之为proto3),它在我们现存的语言版本(proto2)上引进了一些新特性。proto3简化了protocol buffer language,这使其可以更便于使用和支持更多的编程语言:我们现在的alpha release版本可以让你能产生JAVA、C++、Pthyon、JavaNano、Ruby、Objective-C和C#版本的protocol buffer code,不过可能有时会有一些局限性。另外,你可以使用最新的Go protoc插件来产生Go语言版本的proto3 code,这可以从golang/protobuf Github repository获取。

我们现在只推荐你使用proto3:

1、如果你想尝试在我们新支持的语言中使用protocol buffers

2、如果你想尝试我们最新开源的RPC实现gRPC(目前仍处于alpha release版本),我们建议你为所有的gRPC 服务器和客户端都使用proto3以避免兼容性问题。

注意两个版本的语言APIs并不是完全兼容的,为了避免给原来的用户造成不便,我们将会继续维护之前的那个版本(译注:proto2)。

 六、最后说一点历史

Protocol buffers最初被Google开发用来作为处理索引服务器的request/response协议。在protocol buffers诞生之前,有一个需要手动编码/解码requests、responses的协议,这个协议支持一个数字版本号,这导致了一个非常丑陋的代码,如下所示:

1 if (version == 3) {
2    ...
3  } else if (version > 4) {
4    if (version == 5) {
5      ...
6    }
7    ...
8  }

很显然的,格式化的协议也导致了复杂的新版本推出问题,因为开发人员必须确保所有服务器请求的发起者和实际的请求处理者之间都要理解新的协议。

Protocol buffers就是用来解决这些问题的:

1、可以很容易的插入新字段,中间的服务器可以简单的解析它而不需要了解所有字段。

2、格式更具有自描述性,可以被不同的语言处理(比如JAVA、C++、Python等)。

3、自动产生序列化和反序列化代码从而避免了手动解析。

4、除了应用在具有短暂生命周期的RPC请求中,人们开始使用protocol buffers 作为一种便利的自描述格式来存储数据(比如在Bigtable中)。

5、服务器的RPC接口开始被声明为协议文件的一部分,通过protocol 编译器产生stub类,该类可以被用户根据实际实现的服务器接口进行重写。

时间: 2024-10-13 02:35:56

protobuf中文教程(第一篇)的相关文章

Swing:LookAndFeel 教程第一篇——手把手教你写出自己的 LookAndFeel

本文是 LookAndFeel 系列教程的第一篇. 是我在对 Swing 学习摸索中的一些微薄经验. 我相信,细致看全然系列之后.你就能写出自己的 LookAndFeel. 你会发现 Swing 原来能够这样美. -------------------------------------------------------------------------------- 引言: 我第一次接触 Java 要追溯到非常多年前做毕业设计的时候. 那天我和同学来到了一个微型软件公司(三程序猿.一会计.

VMware虚拟机从安装到激活再到解决黑屏、卡、死机系列问题教程第一篇

第一篇:首先下面是VMware虚拟机的安装教程: 首先从官网上下载VMware,然后安装,具体安装步骤如下: 1.双击下载好的应用程序,后出现如下页面,会等待1~3分钟: 2.等待完毕后会出现这个页面,点击下一步: 3.出现以下页面就直接点接受和下一步: 4.接下来这个页面是自定义安装页面,点击更改安装到你想要安装的目录,如果不需要则直接点击下一步(个人建议不要安装在C盘(系统盘)): 5.用户体验设置可根据自己想法自行选择,勾不勾选对安装并无影响,之后点击下一步: 6.快捷方式页面直接默认下一

微信公众号开发入门教程第一篇

关键字:微信公众平台开发作者:方倍工作室 在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/JS等基础. 我们将使用微信公众账号方倍工作室作为讲解的例子,二维码见底部. 本系列教程将引导你完成如下任务: 创建新浪云计算平台应用 启用微信公众平台开发模式 体验常用接收消息及发送消息类型 了解数据收发原理及消息格式 第一章 申请服务器资源 创建新浪云计算应用 申请账号 我们使用SAE新浪云计算平台作为服务器资源,并且申请PH

业余草 SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(Finchley版本)

一.spring cloud简介 鉴于<史上最简单的Spring Cloud教程>很受读者欢迎,再次我特意升级了一下版本,目前支持的版本为Spring Boot版本2.0.3.RELEASE,Spring Cloud版本为Finchley.RELEASE. Finchley版本的官方文档如下: http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html spring cloud 为开发

Vue入门教程 第一篇 (概念及初始化)

注:为了本教程的准确性,部分描述引用了官网及网络内容. 安装Vue 1.使用npm安装vue: npm install vue 2.下载使用js文件: https://vuejs.org/js/vue.min.js Vue概念 Vue (读音 /vju?/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合.另一方面,当与现代化的工具链以及各种支持类库结

极简估值教程——第一篇 速判估值与PEG的推导

来自盛京剑客的雪球原创专栏 一.极简速判估值怎么判? 很简单.简单到粗暴. 用PEG PEG=PE/(g*100)=1.0 什么意思? PE市盈率,g未来收益增长率,PEG为1.0合理估值,大于1.0可能高估,小于1.0可能低估. 例一:已知盛京面包股票当前市盈率为50倍,券商等研究机构预计未来净利润增长率为20%,问PEG为多少?是否高估? 解:PEG=PE/(g100)=50/(0.2100)=2.5 因为PEG=2.5>1.0,所以高估 例二:已知奉天酱油股票,券商等研究机构预计未来净利润

Pentaho BIServer Community Edtion 6.1 使用教程 第一篇 软件安装

一.简介: Pentaho BI Server 分为企业版和社区版两个版本.其中 社区版 CE(community edtion) 为免费版本. 二.下载CE版(CentOS): 后台下载命令: nohup wget -b -c -q http://jaist.dl.sourceforge.net/project/pentaho/Business%20Intelligence%20Server/6.1/biserver-ce-6.1.0.1-196.zip & 三.安装 unzip biserv

CodeIgniter 入门教程第一篇:信息发布

一.MVC CodeIgniter 采用MVC架构即:控制层.模型层和视图层. 对应Application下面的文件夹   (图1): 所有新建文件以.php结尾 视图层 view 文件夹放入HTML模板 模型层 model 存放对数据库操作的代码 控制层 controllers 存放进行逻辑判断的代码,从模型层取得数据然后输入到视图层,发送给用户. 图1 功能: 1. 模板增加输入表单 2. 控制器增加接收表单数据的代码,并对用户输入进行简单校验. 3. 在表单上方输出标题和正文,以及发布时间

Node.js入门教程 第一篇 (环境配置及概念原理)

Node.js 概念 Node.js本质上是使用Google的V8引擎制作出来的服务框架.V8本身是Google为了解决Chrome浏览器的性能问题而制作的前端引擎(开源).本身依托于浏览器引擎,这也是为什么Node.js使用的是前端的JavaScript语言编程. V8的诞生是Google为了解决JavaScript的性能问题,用了内联缓存和隐藏类技术实现的前端引擎.V8使用C++编写,也因此V8可以在C++项目中完美兼容使用. V8被Google使用在大多数产品中,如Chrome浏览器,安卓