Google Protocol Buffers 概述 转

Google Protocol Buffers 概述

个人小站,正在持续整理中,欢迎访问:http://shitouer.cn

小站博文地址:Google Protocol Buffers 概述

推荐阅读顺序,希望给你带来收获~

Google Protocol Buffers 概述

Google Protocol Buffers 入门

Protocol Buffers 语法指南

Google Protocol Buffers 编码(Encoding)

1. 概述

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

本文概述介绍Protocol Buffers,以及开始如何开始Protocol Buffers之旅,本系列主要以Java为主(虽然超想看Python的,无奈学的还不够...)。

以下Protocol Buffers简称PB。

2. Protocol Buffers是什么

Protocol Buffers提供了一种灵活,高效,自动序列化结构数据的机制,可以联想XML,但是比XML更小,更快,更简单。仅需要自定义一次你所需的数据格式, 然后用户就可以使用Protocol Buffers自动生成的特定的源码,方便的读写用户自定义的格式化的数据。不限语言,不限平台。还可以在不破坏原数据格式的基础上,依据老的数据格式, 更新现有的数据格式。

3. Protocol Buffers如何工作的

在PB中,有一种.proto类型的文件,用户 在.proto文件中定义PB “Message”来指定所需要序列化的数据的格式。每一个PB Message都是一个小的信息逻辑单元,包含了一些列的name-value对。下面举例说明一个简单地.proto文件,他定义了一条包含一个 Person信息的Message:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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;

}

如上代码所示,PB message 格式非常简单。每种类型的message包含一个或者多个唯一编码字段,每个字段由名称和值类型组成,值类型可以使数字(整形或者浮点型),布尔值,字符 串,原始字节,甚至是其他的PB message。PB允许message中包含message,已达到分层嵌套。可以定义可选字段,必填字段以及重复字段。想要了解更多如何 写.proto 文件,可以访问:Protocol Buffer Language Guide

定 义好PB message后,选择合适语言的PB编译器,编译.proto文件,就可以生成存取数据的相关类。这些类包括简单的设置及读取字段的方法,也包括对整个 数据结构的message与二进制之间的转换。举个例子,如果你使用的语言是java,运行编译器编译上例.proto文件后,生成的类中包含一个 Person类。使用该类,就可以计算,序列化以及检索PB message。如下代码:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public static void main(String[] args) throws IOException {

    Person john = Person

            .newBuilder()

            .setId(1)

            .setName("john")

            .setEmail("[email protected]")

            .addPhone(

                PhoneNumber

                    .newBuilder()

                    .setNumber("1861xxxxxxx")

                    .setType(PhoneType.WORK)

                    .build())

            .build();

    FileOutputStream output = new FileOutputStream("abc.txt");

    john.writeTo(output);

    output.close();

}

接下来,你可以用如下代码读取:

?


1

2

3

4

5

6

7

8

9

10

public static void main(String[] args) throws IOException {

    FileInputStream input = new FileInputStream("abc.txt");

    Person person = Person.parseFrom(input);

    System.out.println(person.getId());

    System.out.println(person.getName());

    System.out.println(person.getEmail());

    System.out.println(person.getPhoneCount());

    System.out.println(person.getPhone(0).getNumber());

    System.out.println(person.getPhone(0).getType());

}

PB是易于扩展的,可以向后兼容的,我们可以在PB message中添加新的字段,这样,在parse的时候,老版本的数据就会简单的忽略新增加的字段。因此,如果现有通信协议使用了PB作为其数据格式,我们可以直接扩展该通信协议,而不必担心这将会破坏现有的代码。

对于使用.proto文件生成PB 客户端代码,可以参看这方面的完整教程:API Reference section。想要学习了解PB message是如何编码的,可以参见:Protocol Buffer Encoding

4. 为什么不直接使用XML呢?

如果要序列化结构化数据,比起XML,PB实在是有许多的优点可以道道~

  1. 更简单
  2. 比XML小3~10倍
  3. 比XML快20~100倍
  4. 语义定义明确
  5. 自动生成数据存取类,更容易使用

假如我们要模拟一个Person,该对象包含name和email属性,如果用XML,我们定义如下:

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

对应的,PB如下:

person {
  name: "John Doe"
  email: "[email protected]"
}

请注意:这里仅是PB格式的一种直观表示,真实的PB并非这样存储,实际上,在链路中,PB数据时二进制格式的。

当这段数据编码为PB二进制格式时,其实际大小大概是28bytes,编码时间为100~200纳秒。如果用XML的话,即使去除空格,大小也至少为69bytes,编码时间大概需要5000~10,000纳秒。

同样,解析这段代码,PB比XML要方便许多。用PB的话:

person.getName();
person.getEmail();

而用XML的话:

personNode.getElementsByTagName("name")
personNode.getElementsByTagName("email")

相比起来,PB更直接,而且不需要遍历节点等XML操作。

但是,金无足赤,人无完人,PB也一样。对于有很多标签的,基于文本的数据(例如HTML),XML就完胜PB。XML是子描述的,可以随机且交错读取读取文本节点。XML是自描述的,而PB不是,PB必须要有格式定义文件(.proto 文件)

5. 一点历史

PB由Google开发,最初是用于处理索引服务器的请求/响应协议。在有PB之前,Google使用手动编组和解组的方式来处理请求/相应协议。这种方式需要支持许多版本的协议,这就导致一些代码非常的丑陋,例如:

if (version == 3) {
   ...
 } else if (version > 4) {
   if (version == 5) {
     ...
   }
   ...
 }

另外,这种显示格式的协议同样将新发布的协议版本也搞得非常复杂,因为开发者必须在启用新的协议之前,确认所有的服务器,包括请求的发起者以及实际处理请求者,他们都能够理解新的协议。

PB即被设计来解决这些问题:

  1. 要可以非常容易的引入新字段,不需要检查数据的中间服务器 能够简单地解析数据,并且无须知道数据所有的字段就可以传输数据。
  2. 格式能够更加的自描述一些,并且可以被多用语言处理(C ++, Java,Python等)

至此,虽然解决了诸多问题,但用户依然需要手写他们的解析及编码代码。

随着系统的发展,PB逐渐形成了许多新的特性及用法:

  1. 自动生成序列化及反序列化代码,避免手动解析
  2. 除了被用在短生命周期的RPC请求,也开始将PB作为一种方便的自描述格式去存储持久化数据。
  3. Server RPC interfaces 开始被声明为协议文件的一部分,使用PB compiler 生成stub类,用户可以使用自己实现的服务器接口来覆盖他们。

Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们用于 RPC 系统和持续数据存储系统。

译自:https://developers.google.com/protocol-buffers/docs/overview

初次尝试翻译,诸多不够信达雅之处,还望能够不吝指出不到之处,谢谢~

Google Protocol Buffers 概述 转

时间: 2024-10-16 22:27:55

Google Protocol Buffers 概述 转的相关文章

Google Protocol Buffers 编码(Encoding)

Google Protocol Buffers 编码(Encoding) 1. 概述 前三篇文章<Google Protocol Buffers 概述><Google Protocol Buffers 入门><Protocol Buffers 语法指南> 一步一步将大家带入Protocol Buffers的世界,我们已经基本能够使用Protocol Buffers生成代码,编码,解析,输出级读入序列化数据.该篇主要讲述PB message的底层二进制格式.不了解该部分内

Google Protocol Buffers 入门

1. 前言 这篇入门教程是基于Java语言的,这篇文章我们将会: 创建一个.proto文件,在其内定义一些PB message 使用PB编译器 使用PB Java API 读写数据 这篇文章仅是入门手册,如果想深入学习及了解,可以参看: Protocol Buffer Language Guide, Java API Reference, Java Generated Code Guide, 以及Encoding Reference. 2. 为什么使用Protocol Buffers 接下来用“

Google Protocol Buffers 快速入门(带生成C#源码的方法)

Google Protocol Buffers是google出品的一个协议生成工具,特点就是跨平台,效率高,速度快,对我们自己的程序定义和使用私有协议很有帮助. Protocol Buffers入门:1.去 http://code.google.com/p/protobuf/downloads/list 下载一个源代码包和一个已编译好的二进制包2.找一个Proto示例代码,使用命令 protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbo

C#下使用protobuf(Google Protocol Buffers)

Protobuf是google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言,其最大的特点是基于二进制,因此比传统的XML表示高效短小得多.除了比Json.XML有速度上的优势和使用上的方便外,protocolbuf还可以做到向前兼容和向后兼容. protobuf 虽然只支持JAVA.C++和Pyton,但protobuf社区的protobuf.net组件让protobuf可以支持更多的语言,其中就包括了C#. protobuf协议 定义protobuf协议必须创建一个以.p

Google protocol buffers 小结(二)

protobuf是什么 protobuf,全称Google protocol buffer,Google公司内部的混合语言数据标准,用于RPC系统和持续数据存储系统 它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化,适合做数据存储或RPC数据交换格式,可用于通讯协议.数据存储等领域的语言无关.平台无关.可扩展的序列化结构数据格式.目前提供了 C++.Java.Python三种语言的 API 为什么要使用protobuf 提到protobuf,一般会与XML做比较,pr

DELPHI、FLASH、AS3、FLEX使用Protobuf(google Protocol Buffers)的具体方法

最近因为工作需要,需要在不同的开发环境中应用Protobuf,特此,我专门研究了一下.为了防止自己忘记这些事情,现在记录在这里!需要的朋友可以借鉴一些,因为这些东西在GOOGLE和百度上搜索起来真的很费劲! 一.首先说DELPHI的. 因为DELPHI现在用的人不多了,所以找这个东西真心不好找!还好,加了几个QQ群,有用过的朋友告诉了我! 具体步骤如下: 1.下载DELPHI使用Protobuf需要的项目. 地址在这里:http://sourceforge.NET/projects/fundem

Protocol Buffers 语法指南

前两篇文章,我们概括介绍<Google Protocol Buffers 概述>以及带领大家简单的<Google Protocol Buffers 入门>,接下来,再稍微详细一点介绍Protocol Buffers书写语言.该篇文章主要讲解如何使用PB语言构建数据,包括.proto文件语法及如果使用.proto文件生成数据存取类. 本篇主要包括: 定义一个PB message类型 介绍PB 数据类型 Optional字段及其默认值 枚举类型 使用其他Message类型作为filed

(转)Protocol Buffers for C

我一直不太满意 google protocol buffers 的默认设计.为每个 message type 生成一大坨 C++ 代码让我很难受.而且官方没有提供 C 版本,第三方的 C 版本 也不让我满意. 这种设计很难让人做动态语言的 binding ,而大多数动态语言往往又没有强类型检查,采用生成代码的方式并没有特别的好处,反而有很大的性能损失(和通常做一个 bingding 库的方式比较).比如官方的 Python 库,完全可以在运行时,根据协议,把那些函数生成出来,而不必用离线的工具生

java&amp;Protocol Buffers

ps: Protocol Buffers简称PB PB 安装配置 下载 PB: 在 PB 官网,下载最新版(或者其他版本)PB,这里为了与 Java 项目中的 PB Maven 依赖版本一致,使用 PB 2.5.0 版本. 安装 PB: 解压:tar zxvf protobuf-2.5.0.tar.gz,使用 cd 命令进入 protobuf-2.5.0 目录. ./configure,通常建议加上 --prefix 参数来指定目录,例如:./configure --prefix=/usr/lo