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. Java:对象的强、软、弱和虚引用的区别

    1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...

  2. canvas猜数游戏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. erlang尾递归练习

    1 %%计算链表长度尾递归实现 2 lez(N) -> lez(N, 0). 3 4 lez([], Acc) -> Acc; 5 lez([_ | T], Acc) -> lez( ...

  4. 【LDAP】LDAP常用命令解析

    ldapadd -x   进行简单认证-D   用来绑定服务器的DN-h   目录服务的地址-w   绑定DN的密码-f   使用ldif文件进行条目添加的文件例子 ldapadd -x -D &qu ...

  5. 基于Flume做FTP文件实时同步的windows服务。

    需求:做一个windows服务,实现从ftp服务器实时下载或者更新文件到本地磁盘. 功能挺简单的.直接写个ftp工具类用定时器跑就能搞定,那我为什么不用呢? 别问,问就是我无聊啊,然后研究一下Flum ...

  6. PTA (Advanced Level) 1013 Battle Over Cities

    Battle Over Cities It is vitally important to have all the cities connected by highways in a war. If ...

  7. file_get_contents 抓取网页乱码。

    iconv string iconv ( string $in_charset , string $out_charset , string $str ) mb_convert_encoding st ...

  8. python实例:快速找出多个字典中的公共键

    1.生成随机字典 # 从abcdefg 中随机取出 3-6个,作为key, 1-4 的随机数作为 value s1 = {x : randint(1, 4) for x in sample('abcd ...

  9. SQL:存储过程

    1/什么是存储过程及概念 Transact-SQL中的存储过程,非常类似于.Net语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这样就可 ...

  10. 通过开机广播(broadcast)通知应用

    1. 概念 开机的时候,系统会发送一则广播,所有有标记的应用(通过广播接收者)都会获取得到,然后可以通过广播接收者去处理一些事情,比如启动该应用,或者处理数据: 代码:https://github.c ...