Protocol Buffer学习笔记
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高效 |
|
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; } |
表示可为字段指定某“预定义序列值”的一个值,来表示某一类型,如果为 |
||||
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 |
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学习笔记的更多相关文章
- Protocol Buffers学习笔记
Protocol Buffers学习笔记 1. 简介 Protocol Buffers是google发明的一种数据交换格式,独立于语言,独立于平台.与其他的数据交换格式有所不同,Protocol Bu ...
- Protocol Buffer学习教程之类库应用(四)
Protocol Buffer学习教程之类库应用(四) 此教程是通过一个简单的示例,给C++开发者介绍一下如何使用protocol buffers编程,主要包括以下几部分: 定义一个.proto文件 ...
- Protocol Buffer学习教程之编译器与类文件(三)
Protocol Buffer学习教程之编译器与类文件(三) 1. 概述 在前面两篇中,介绍了Protobuf的基本概念.应用场景.与protobuf的语法等.在此篇中将介绍如何自己编译protobu ...
- Protocol Buffer学习教程之开篇概述(一)
1. Protocol Buffer是什么 Protocol Buffer是google旗下的产品,用于序列化与反序列化数据结构,但是比xml更小.更快.更简单,而且能跨语言.跨平台.你可以把你的数据 ...
- Protocol Buffer学习教程之语法手册(二)
1.说明 此向导介绍如何使用protocol buffer language创建一个自己的protocolbuffer文件,包括语法与如何通过“.proto”文件生成数据访问的类,此处只介绍proto ...
- Buffer学习笔记.
前言 JavaScript 对于字符串的操作十分便捷,无论是单字节字符还是宽字节字符,都会认为是一个字符.对字符串的简单操作和DOM操作基本上已经可以满足前端工程需求,但Node很多时候需要处理文件和 ...
- TCP(Transmission Control Protocol)学习笔记
一.TCP(Transmission Control Protocol)原理介绍(参考维基百科) TCP连接包括三种状态:连接建立.数据传送和连接终止. TCP用三路握手(three-way hand ...
- RTSP(Real Time Streaming Protocol)学习笔记 -- RFC2326
Real Time Streaming Protocol (RTSP) RTSP是用在娱乐或通讯中控制流媒体服务器的网络协议,它可以创建和控制两个端点之间的会话. Client发出一些命令来控制me ...
- 学习Google Protocol buffer之语法
上一篇结尾的时候问了几个问题,其实主要就是这个protoBuffer协议的语法,弄清楚语法后边才好开展工作嘛,不然大眼而对小眼儿,互相不认识,就没法玩耍了.其实就是学习怎么用google提供的这套 p ...
随机推荐
- masm32环境配置
软件: Windows7-32bit visual c++6.0 Masm32 sdk 11 安装: 0x00 || 下载Masm sdk 11并安装,下载路径:http://www.masm32.c ...
- destoon调用方法汇总 ---转载
根目录.模板目录和样式目录:{DT_PATH}{DT_SKIN}导入头脚:{template 'header'}{template 'footer'}对应模块首页:{$MODULE[$moduleid ...
- 修改VS项目的目标平台(目标框架)
如果是正常的情况下.. 右键项目属性里就有修改的地方.. 可是有时候打开属性发现修改的下拉框是禁用的.. 这时候可以右键 "卸载项目" 编辑 .csproj 项目文件 在上方有个& ...
- 开源一个Java Class实现Openfire登陆、推出、消息发送,方便其他系统集成IM功能了
开源一个Java Class实现Openfire登陆.推出.消息发送 N年前写的,希望对Openfire开发新手有帮助哦 import java.util.*; import java.io.*; ...
- 释放linux端口
感谢作者的共享,在此表示感谢 有时候关闭软件后,后台进程死掉,导致端口被占用.下面以TOMCAT端口8060被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln ...
- 使用C++11 开发一个半同步半异步线程池
摘自:<深入应用C++11>第九章 实际中,主要有两种方法处理大量的并发任务,一种是一个请求由系统产生一个相应的处理请求的线程(一对一) 另外一种是系统预先生成一些用于处理请求的进程,当请 ...
- vue中添加Echarts图表的使用,Echarts的学习笔记
项目中需要使用一些折线图.柱状图.饼状图等等,之前使用过heightCharts(关于heightCharts请看我的另一篇 http://www.cnblogs.com/jasonwang2y60/ ...
- Codeforces 985G. Team Players
Description 有 \(n\) 个人 , \(m\) 对人有冲突 , 你要从这 \(n\) 个人中选出三个人成为一组 , 使得同一组的人不存在一对有冲突 题面 Solution 容斥 答案=总 ...
- TCP/IP提供网络传输速率
丢包(超时)->减少超时时间->ECN(有网络设备通知终端,有丢包发生)->DCTCP(优化快恢复) 丢包是超时的充分条件,但不是必要条件,因此也可通过其他方式获得丢包是否发生,比如 ...
- unity assetStore 常用插件
常用插件 20180723============= 教程类 =============<Mecanim Example Scenes > 官方示例场景<Surivial Shoot ...