Protobuf 语法 - 史上最简教程
Protobuf 语法简明教程
疯狂创客圈 死磕Netty 亿级流量架构系列之12 【博客园 总入口 】
在protobuf中,协议是由一系列的消息组成的。因此最重要的就是定义通信时使用到的消息格式。
一个Protobuf 消息(对应JAVA类),由至少一个字段(对应Java类属性)组合而成。
每个Protobuf 消息的 字段 都有一定的格式。
字段格式:
限定修饰符① | 数据类型② | 字段名称③ | = | 字段编码值④ | [字段默认值⑤]
①.限定修饰符包含 required\optional\repeated
Required:
表示是一个必须字段,必须相对于发送方,在发送消息之前必须设置该字段的值,对于接收方,必须能够识别该字段的意思。发送之前没有设置required字段或者无法识别required字段都会引发编解码异常,导致消息被丢弃。
Optional:
表示是一个可选字段,可选对于发送方,在发送消息时,可以有选择性的设置或者不设置该字段的值。对于接收方,如果能够识别可选字段就进行相应的处理,如果无法识别,则忽略该字段,消息中的其它字段正常处理。---因为optional字段的特性,很多接口在升级版本中都把后来添加的字段都统一的设置为optional字段,这样老的版本无需升级程序也可以正常的与新的软件进行通信,只不过新的字段无法识别而已,因为并不是每个节点都需要新的功能,因此可以做到按需升级和平滑过渡。
Repeated:
表示该字段可以包含0~N个元素。其特性和optional一样,但是每一次可以包含多个值。可以看作是在传递一个数组的值。
②.数据类型
Protobuf定义了一套基本数据类型。几乎都可以映射到C++\Java等语言的基础数据类型.
protobuf 数据类型 | 描述 | 打包 | C++语言映射 |
---|---|---|---|
bool | 布尔类型 | 1字节 | bool |
double | 64位浮点数 | N | double |
float | 32为浮点数 | N | float |
int32 | 32位整数、 | N | int |
uin32 | 无符号32位整数 | N | unsigned int |
int64 | 64位整数 | N | __int64 |
uint64 | 64为无符号整 | N | unsigned __int64 |
sint32 | 32位整数,处理负数效率更高 | N | int32 |
sing64 | 64位整数 处理负数效率更高 | N | __int64 |
fixed32 | 32位无符号整数 | 4 | unsigned int32 |
fixed64 | 64位无符号整数 | 8 | unsigned __int64 |
sfixed32 | 32位整数、能以更高的效率处理负数 | 4 | unsigned int32 |
sfixed64 | 64为整数 | 8 | unsigned __int64 |
string | 只能处理 ASCII字符 | N | std::string |
bytes | 用于处理多字节的语言字符、如中文 | N | std::string |
enum | 可以包含一个用户自定义的枚举类型uint32 | N(uint32) | enum |
message | 可以包含一个用户自定义的消息类型 | N | object of class |
N 表示打包的字节并不是固定。而是根据数据的大小或者长度。
例如int32,如果数值比较小,在0~127时,使用一个字节打包。
关于枚举的打包方式和uint32相同。
关于message,类似于C语言中的结构包含另外一个结构作为数据成员一样。
关于 fixed32 和int32的区别。fixed32的打包效率比int32的效率高,但是使用的空间一般比int32多。因此一个属于时间效率高,一个属于空间效率高。根据项目的实际情况,一般选择fixed32,如果遇到对传输数据量要求比较苛刻的环境,可以选择int32.
③.字段名称
字段名称的命名与C、C++、Java等语言的变量命名方式几乎是相同的。
protobuf建议字段的命名采用以下划线分割的驼峰式。例如 first_name 而不是firstName.
④.字段编码值
有了该值,通信双方才能互相识别对方的字段。当然相同的编码值,其限定修饰符和数据类型必须相同。
编码值的取值范围为 1~2^32(4294967296)。
其中 1~15的编码时间和空间效率都是最高的,编码值越大,其编码的时间和空间效率就越低(相对于1-15),当然一般情况下相邻的2个值编码效率的是相同的,除非2个值恰好实在4字节,12字节,20字节等的临界区。比如15和16.
1900~2000编码值为Google protobuf 系统内部保留值,建议不要在自己的项目中使用。
protobuf 还建议把经常要传递的值把其字段编码设置为1-15之间的值。
消息中的字段的编码值无需连续,只要是合法的,并且不能在同一个消息中有字段包含相同的编码值。
建议:项目投入运营以后涉及到版本升级时的新增消息字段全部使用optional或者repeated,尽量不实用required。如果使用了required,需要全网统一升级,如果使用optional或者repeated可以平滑升级。
⑤.默认值。
当在传递数据时,对于required数据类型,如果用户没有设置值,则使用默认值传递到对端。当接受数据是,对于optional字段,如果没有接收到optional字段,则设置为默认值。
关于import
protobuf 接口文件可以像C语言的h文件一个,分离为多个,在需要的时候通过 import导入需要对文件。其行为和C语言的#include或者java的import的行为大致相同。
关于package
避免名称冲突,可以给每个文件指定一个package名称,对于java解析为java中的包。对于C++则解析为名称空间。
关于message
支持嵌套消息,消息可以包含另一个消息作为其字段。也可以在消息内定义一个新的消息。
关于 enum
枚举的定义和Java 相同,但是有一些限制。
枚举值必须大于等于0的整数。
使用分号(;)分隔枚举变量而不是Java 语言中的逗号(,)
eg.
enum VoipProtocol
{
H323 = 1;
SIP = 2;
MGCP = 3;
H248 = 4;
}
疯狂创客圈 实战计划
- Netty 亿级流量 高并发 IM后台 开源项目实战
- Netty 源码、原理、JAVA NIO 原理
- Java 面试题 一网打尽
- 疯狂创客圈 【 博客园 总入口 】
Protobuf 语法 - 史上最简教程的更多相关文章
- SpringBoot整合SpringKafka实现消费者史上最简代码实现
该项目是使用的技术:SpringBoot + SpringKafka + Maven 先看pom.xml文件中引入的依赖: <?xml version="1.0" enco ...
- SpringBoot整合SpringKafka实现生产者史上最简代码实现
该项目是使用的技术:SpringBoot + SpringKafka + Maven 先看pom.xml文件中引入的依赖: <?xml version="1.0" enco ...
- ansj分词史上最详细教程
最近的项目需要使用到分词技术.本着不重复造轮子的原则,使用了ansj_seg来进行分词.本文结合博主使用经过,教大家用最快的速度上手使用ansj分词. 1.给ansj来个硬广 项目的github地址: ...
- rocketmq 4.2.0 版本 控制台本地搭建(史上最简单教程)
就像发现新大陆一般,瞎折腾,搞出来了..并没有网上说的一大串....(本人公司的项目从未使用过springboot....) rocketmq 控制台,官方使用springboot 做后端,前端使用 ...
- Python 极简教程(八)字符串 str
由于字符串过于重要,请认真看完并保证所有代码都至少敲过一遍. 对于字符串,前面在数据类型中已经提到过.但是由于字符串类型太过于常用,Python 中提供了非常多的关于字符串的操作.而我们在实际编码过程 ...
- 史上最简单的 MySQL 教程(十五)「列属性 之 自动增长」
自动增长 自动增长:auto_increment,当对应的字段,不给值,或者是默认值,或者是null的时候,就会自动的被系统触发,系统会从当前字段中取已有的最大值再进行+1操作,得到新的字段值. 自增 ...
- Vue2.0史上最全入坑教程(下)—— 实战案例
书接上文 前言:经过前两节的学习,我们已经可以创建一个vue工程了.下面我们将一起来学习制作一个简单的实战案例. 说明:默认我们已经用vue-cli(vue脚手架或称前端自动化构建工具)创建好项目了 ...
- sentinel (史上最全+入门教程)
文章很长,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈 为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 < Java 高并发 三部曲 > 面试必备 + 大厂 ...
- [分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例)
[分享] 史上最简单的封装教程,五分钟学会封装系统(以封装Windows 7为例) 踏雁寻花 发表于 2015-8-23 23:31:28 https://www.itsk.com/thread-35 ...
随机推荐
- ElasticSearch的按日期排序问题
ES中有一个sort域,类型为date,格式是: yyyy-MM-dd HH:mm:ss 但是,在实际应用中,想仅仅按yyyy-MM-dd排序.我的处理过程是,用es的script,提取出日期,然后按 ...
- 转:Eclipse自动补全功能轻松设置
Eclipse自动补全功能轻松设置 || 不需要修改编辑任何文件 2012-03-08 21:29:02| 分类: Java | 标签:eclipse 自动补全 设置 |举报|字号 订阅 ...
- java 实体序列化的意义
一.序列化的意义 客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间.如果在某一时间段内访 ...
- www.mentalis.org/
Top Downloads Here are the top downloads (within the last 24 hours): 1. Proxy2. IniReader3. ProxySoc ...
- MySQL日期函数的用法几则
1.将Date类型变成年月日时分秒的形式 select date_format(claimDate,'%Y-%m-%d %H:%i:%s') as claimdate from t1 2.只要年月日的 ...
- iOS_新版iOS11 UITbleView适配的一些问题及解决方法
// tableView 偏移20/64适配 if (@available(iOS 11.0, *)) { self.tableView.contentInsetAdjustmentBehavior ...
- SQL SERVER 使用订阅发布同步数据库(转)
一.数据库复制涉及 1.发布服务器: 数据的来源服务器,维护源数据,决定哪些数据将被分发,检测哪些数据发生了修改,并将这些信息提交给分发服务器. 2.分发服务器: 分发服务器负责把从发布服务器拿 ...
- odoo分析会计
odoo财务会计凭证录入时,支持 在凭证行 输入 分析账户和 分析标签 如果凭证行设置了 分析账户或者分析标签, 则在会计凭证过账的时候, 在分析会计功能建立 分析会计分录 其中, 如果设置了分析账户 ...
- SQL优化的一些总结 SQL编写一般要求
SQL编写一般要求---SQL语句尽可能简单---分解联接保证高并发---同数据类型的列值比较---不在索引列做运算---禁止使用SELECT *---避免负向查询和%前缀模糊查询---保持事务(连接 ...
- 如何在aspx页面中使用ascx控件(用户自定义的一个控件)?
aspx是页面文件ascx是用户控件,用户控件必须嵌入到aspx中才能使用. ascx是用户控件,相当于模板 其实ascx你可以理解为Html里的一部分代码,只是嵌到aspx里而已,因为aspx内容多 ...