公司项目使用了gRPC, 刚从java转go的我实在是搞不懂。百度了参考各种资料,在这里做个记录。
参考:https://blog.csdn.net/carson_ho/article/details/70568606
定义:
一种 结构化数据 的数据存储格式。(类似于xml, json)
作用:
通过将 结构化的数据 进行串行化(序列化),从而实现 数据存储/rpc数据交换 的功能
序列化:将数据结构或对象 转换成 二进制的 过程
饭序列化:将在序列化过程中所生成的二进制串 转换成 数据结构或对象 的过程。
特点:
相对于xml,json,protocol buffer有如下特点:
应用场景:
传输数据量大 & 网络环境不稳定的数据存储 、rpc数据交换的需求场景。
序列化原理解析:
序列化本质:对数据进行编码 + 存储
1. 序列化速度快:
编码/解码 方式简单(只需简单的数学运算= 位移等)
采用pb自身的框架代码 和编译器共同完成
2. 序列化后体积小(数据压缩效果好)
采用了独特的编码方式,如Varint, Zigzag等
采用T - L - V 的数据存储方式,
即
Tag - Length - Value
,标识 - 长度 - 字段值 存储方式,减少了分隔符的使用,数据存储得紧凑
使用步骤:
1. 环境配置
1.1 下载protocol buffer
1.2 安装HOMEBREW
1.3 安装protocol buffer
2. 构建protocol buffer消息对象模型
2.1 通过protocol buffer语法,描述需要存储的数据结构:.proto文件
2.2 通过protocol buffer 编译器,编译.proto文件(生成对应平台的代码文件)
proto3语法
1.定义消息类型
syntax = "proto3"; message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3; }
文件第一行指定了使用的proto3语法,如果不指定,默认使用proto2.这个语句必须在.proto文件的非空非注释的第一行。
可见请求消息结构体中定义了3个字段:query,page_number, result_per_page,每个字段都有名称和类型。
指定字段类型:
上面的3个字段都是值类型,两个整型和一个字符串类型。可以指定字段的组合类型,包括枚举和其他消息类型。
分配标识---tag:
消息请求结构体中每个字段都有唯一的数字标识,这些标识用来在消息的二进制格式中识别你的字段,并且一旦消息投入使用,这些标识就不应该再被修改。
标识1-15使用一个字节编码,包括数字和字段类型;标识16-2047使用两个字节编码。所以应该保留1-15,用作出现最频繁的消息类型的标识,不要把1-15用完,为以后留点。
可以指定最小的标识数字为1,最大为229 - 1, or 536,870,911,或者536 870 911.不能使用19000-19999之间的数字,是protocol buffers的保留标识。
指定字段规则:
消息字段可以是以下的一种:
1. singular(单个):符合语法规则的消息包含零个或者一个这样的字段(最多一个)
2. repeated(重复):一个字段在合法的消息中可以重复出现一定的次数(包括零次).重复出现的值的次序将被保留,在proto3中,重复出现的值类型字段默认采用压缩编码。
添加更多消息类型:
多个消息类型可以定义在一个.proto文件中。这样在定义多个关联的消息的时候很有用,如:
message SearchRequest { string query = 1; int32 page_number = 2; int32 result_per_page = 3; } message SearchResponse { ... }
添加注释:
message SearchRequest { string query = 1; int32 page_number = 2; // Which page number do we want? int32 result_per_page = 3; // Number of results to return per page. }
编译.proto文件
.proto文件编译之后,编译器会为你选择的语言生成代码。在文件中描述的消息类型,包括获取和设置字段的值,序列化你的消息到一个输出流,以及从一个输入流中转换出你的消息。
1.c++,编译器会为每个.proto文件生成一个.h和一个.cc的文件,为每一个给出的消息类型生成一个类。
2.java,编译器会生成一个java文件,其中为每个消息类型生成一个类,还有特殊的用来创建这些消息类实例的Builder类。
3.python,会生成一个模块,为每个消息类型生成一个静态的描述器,在运行时,和一个metaclass一起使用来创建必要的python数据访问类。
4.go:为每个消息类型生成一个.pb.go的文件
5.ruby:每一个.proto生成一个.rb文件
6.objective-c :每个.proto生成一个pbobjc.h和一个pbobjc.m文件
7.c#:每个.proto生成一个.cs文件
值类型
参考: https://www.cnblogs.com/lijunhao/p/6169566.html
字段默认值:
1.string ,默认值是空字符串
2.bytes:默认值是空bytes
3. bools 默认值是false
4.numberic 默认值是0
5. enums: 默认值是第一个枚举值(value必须为0)
6.message fields, the field is not set. Its exact value is langauge-dependent. See the generated code guide for details.
7.repeated fields,默认值为empty,通常是一个空list