Protocol Buffer

Protobuf基础概念

Protobuf是google开发的数据结构描述语言,能够将结构化数据序列化与反序列化,取代json和xml,常用于服务器通信协议、RPC系统和数据持久化存储系统中。

优点:高性能,数据协议小,平台无关,语言无关,向前和向后兼容

缺点:通用性比XML差,以二进制存储,无法直接读取出protobuf的内容。

Protobuf在应用场景之一

客户端程序是使用Java开发的,可能运行自不同的平台,如:Linux、Windows或者是Android,而我们的服务器程序通常是基于Linux平台并使用C++开发完成的。在这两种程序之间进行数据通讯时存在多种方式用于设计消息格式。

Protobuf字段类型对应

Protobuf type

java type

c++ type

protobuf  type  describe

bool

boolean

bool

bytes

ByteString

string

可包含任意顺序的字节数据。

double

double

double

float

float

float

int32

int

int32

使用可变长编码方式。编码负数时不够高效如果字段负数,那么使用sint32更高效

int64

long

int64

使用可变长编码方式。编码负数时不够高效如果字段含有负数,那么使用sint64。

uint32

int

uint32

使用可变长编码方式

unint64

long

uint64

使用可变长编码方式

sint32

int

int32

使用可变长编码方式。有符号的整型值。编码时比通常的int32高效

sint64

long

int64

使用可变长编码方式。有符号的整型值。编码时比通常的int64高效

fixed32

int

uint32

总是4个字节。如果数值总是比2的28次方大的话,这个类型会比uint32高效

fixed64

long

uint64

总是8个字节。如果数值总是比256大的话,这个类型会比uint64高效

sfixed32

int

int32

总是4个字节

sfixed64

long

int64

总是8个字节

string

String

string

一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本

Protobuf关键字说明

关键字

.proto语法

说明

package

package:package_name

包名定义

java_package

java_package:com.example.protobuf

java包路径声明

java-outer_classname

Java-outer_classname:classname

编译后生成的类名的声明

message

required

message MessageName{

required string name=1;

optional int32 id=2;

optional int32 age=3;

}

message消息定义关键字,编译后生成实体类,标签1,2,3在每个消息中必须是唯一的

该字段必须设置,且消息中至少有一个

optional

该字段可以不设置值传递

repeated

该字段可不设置值,java中以List集合表示

service

service ServiceName{

rpc RpcName(MessageName)returns(MessageName){}

}

RPC服务定义

import

import "path/other.proto"

引入其它的.proto文件

enum

enum Corpus {

UNIVERSAL = 0;

WEB = 1;

IMAGES = 2;

LOCAL = 3;

NEWS = 4;

}

表示可为字段指定某“预定义序列值”的一个值,来表示某一类型,如果为
enum修饰的字段指定预定义序列值之外的值,那么解析器就会把它当做未知的值来对待

Protobuf在Java中的使用

安装编译器:

到google官网https://developers.google.com/protocol-buffers下载编译器(最新版为2.6.1),解压安装编译器,也可在该官网查阅Protocol Buffer API帮助文档,目前只有C++、GO、Java、Python和C#的API,

编译.proto文件

a.安装完编译器后可直接在安装目录的Dos环境下编译或是用批处理方式,为了避免造成不必要的麻烦编译失败,而无法查看错误,建议用批处理方式:

proc path_src=$src_path java_out=$out_path $path\filename.proto

pause

将.proto编译成相应的.java文件

Protobuf各类字段在java中设值/取值方式

属性

字段角色

设值方式

取值方式

是否是必设值

有无默认值

required

setX()

getX()

optional

setX()

getX()

repeated

addX()

getX(int index)/getX()

Protobuf应用消息升级规则

1)  原有标签号必须被保留,不能被新字段重用。

2)不能移除和添加required限定符字段。

3)新添加字段必须是optional和required限定符。

4)int32、uint32、int64、uint64和bool等类型之间是兼容的,sint32和sint64是兼容的,string和bytes是兼容的且必须是UTF-8编码,fixed32兼容sfixed32,以及fixed64兼容sfixed64,这意味着如果想修改原有字段的类型时,为了保证兼容性,只能将其修改为与其原有类型兼容的类型。

5)optional限定符兼容repeated限定符。

Protobuf和json对比

浏览器端ProtocolBufer和JSON序列化和反序列化对比

Protocol  Buffer

JSON

数据量

序列化所需时间(ms)

反序列化时间(ms)

所占空间(B)

序列化所需时间(ms)

反序列化时间(ms)

所占空间(B)

10

5

4

190

0

0

490

100

16

15

1900

0

0

4900

1000

59

51

19000

0

2

49000

10000

294

113

190000

1

11

490000

100000

1942

744

1900000

4

95

4900000

1000000

28899

6974

19000000

8

921

49000000

Java 服务端ProtocolBuffer和JSON序列化和反序列化对比

ProtocolBuffer

JSON

数据量

序列化所需时间

反序列化时间

序列化所需时间

反序列化时间

10

30

16

91

40

100

33

15

110

51

1000

42

17

211

106

10000

44

113

581

267

100000

48

20

1014

589

1000000

68

25

3663

1007

Protobuf数据类型编码性能对比

表1

序列化数值

数据类型

序列化次数

序列化所需时间

序列化后编码长度

-2147483648

Int32

100000

113

11

-2147483648

Sint32

100000

35

6

-2147483648

Uint32

100000

29

6

-2147483648

fixed32

100000

29

5

表2

序列化数值

数据类型

序列化次数

序列化所需时间

序列化后编码长度

2147483647

Int32

100000

75

6

2147483647

Sint32

100000

33

6

2147483647

Uint32

100000

28

6

2147483647

fixed32

100000

24

5

表3

序列化数值

数据类型

序列化次数

序列化所需时间

序列化后编码长度

134217728

Int32

100000

75

5

134217728

Sint32

100000

34

6

134217728

Uint32

100000

28

5

134217728

fixed32

100000

26

5

条件:

表1,对负值进行序列化

表2,对正直序列化,且该值2147483647大于2的28次方

表3,对正直序列化,且该值134217728小于2的28次方

Protocol Buffer学习笔记的更多相关文章

  1. Protocol Buffers学习笔记

    Protocol Buffers学习笔记 1. 简介 Protocol Buffers是google发明的一种数据交换格式,独立于语言,独立于平台.与其他的数据交换格式有所不同,Protocol Bu ...

  2. Protocol Buffer学习教程之类库应用(四)

    Protocol Buffer学习教程之类库应用(四) 此教程是通过一个简单的示例,给C++开发者介绍一下如何使用protocol buffers编程,主要包括以下几部分: 定义一个.proto文件 ...

  3. Protocol Buffer学习教程之编译器与类文件(三)

    Protocol Buffer学习教程之编译器与类文件(三) 1. 概述 在前面两篇中,介绍了Protobuf的基本概念.应用场景.与protobuf的语法等.在此篇中将介绍如何自己编译protobu ...

  4. Protocol Buffer学习教程之开篇概述(一)

    1. Protocol Buffer是什么 Protocol Buffer是google旗下的产品,用于序列化与反序列化数据结构,但是比xml更小.更快.更简单,而且能跨语言.跨平台.你可以把你的数据 ...

  5. Protocol Buffer学习教程之语法手册(二)

    1.说明 此向导介绍如何使用protocol buffer language创建一个自己的protocolbuffer文件,包括语法与如何通过“.proto”文件生成数据访问的类,此处只介绍proto ...

  6. Buffer学习笔记.

    前言 JavaScript 对于字符串的操作十分便捷,无论是单字节字符还是宽字节字符,都会认为是一个字符.对字符串的简单操作和DOM操作基本上已经可以满足前端工程需求,但Node很多时候需要处理文件和 ...

  7. TCP(Transmission Control Protocol)学习笔记

    一.TCP(Transmission Control Protocol)原理介绍(参考维基百科) TCP连接包括三种状态:连接建立.数据传送和连接终止. TCP用三路握手(three-way hand ...

  8. RTSP(Real Time Streaming Protocol)学习笔记 -- RFC2326

    Real Time Streaming Protocol (RTSP)  RTSP是用在娱乐或通讯中控制流媒体服务器的网络协议,它可以创建和控制两个端点之间的会话. Client发出一些命令来控制me ...

  9. 学习Google Protocol buffer之语法

    上一篇结尾的时候问了几个问题,其实主要就是这个protoBuffer协议的语法,弄清楚语法后边才好开展工作嘛,不然大眼而对小眼儿,互相不认识,就没法玩耍了.其实就是学习怎么用google提供的这套 p ...

随机推荐

  1. centos 7修改系统支持中文编码

    2019-03-14 查看系统现支持编码 }[root@web dc2-user]#locale LANG=en_US.UTF- LC_CTYPE="en_US.UTF-8" LC ...

  2. 拖进Xshell终端窗口文件上传

    XShell已经内置rz 直接从Windows拖文件进去终端 http://www.jb51.net/LINUXjishu/163820.html 借助securtCRT,使用linux命令sz可以很 ...

  3. JS DATE对象详解

    1.建立时间对象:可获取年,月,日,星期,时,分,秒 var d = new Date(); console.log(d.getFullYear()+'年'+d.getMonth()+'月'+d.ge ...

  4. 003javascript语句

    javascript语句和java差不多,注意==和===区别 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" " ...

  5. jquery mobile 动态加载标签时,无法正常展示样式

    原因 在chrome中审查元素,发现其增加了很多没有直接写在页面上的标签和样式.页面标签首先经过jquery.mobile-1.4.5.min.js的处理,添加了许多标签,然后再用css布局 解决方案 ...

  6. ehcache 集群使用 rmi方式 有图有真想

    来源:http://www.tuicool.com/articles/MJzYZbR ehcache 有几种方式集群 ,rmi,jgroup还有jms:这里讲一下ehcache的使用 ehcache ...

  7. jQuery事件篇---高级事件

    内容提纲: 1.模拟操作 2.命名空间 3.事件委托 4.on.off 和 one 发文不易,转载请注明出处! 一.模拟操作 在事件触发的时候,有时我们需要一些模拟用户行为的操作.例如:当网页加载完毕 ...

  8. C# 时间操作类

    using System; namespace DotNet.Utilities { /// <summary> /// 时间类 /// 1.SecondToMinute(int Seco ...

  9. git merge后,后悔了如何回退

    今天将feature分支的代码merge到develop分支后我后悔了,因为feature分支的功能还没有全部开发完成,我在feature分支上commit是可以的,但是这之后我又把它merge到了d ...

  10. 程序员必备技能:代码审查 (Google牛人谈Code Review)

    在上一篇博客里我暗示自己将不在为Google工作. 我还没有决定好去哪儿-有几个非常不错的工作机会让我选择.鉴于这段时间内我不受雇于任何公司,我想我可以写点和专业相关的东西,这些东西很有趣,但是如果我 ...