概述
一.Protocol Buffers应用场景
1.序列化的应用场景
PB要解决的是序列化的问题,所以我们从序列化的角度去理解PB。
序列化就是将一个数据结构(通常是对象)转换为二进制的行式。
反序列化则是将二进制数据转换为数据结构或对象。
因为在内存中最容易处理的数据行式是对象,而在存储和通信时最容易处理的是二进制数据,因此在面临存储对象和传输对象的场景时,就会需要解决序列化和序列化的问题。
就像ORM解决面向对象和关系数据库的匹配问题一样,序列化也是解决面向对象和存储/通信的匹配问题。
2.序列化面临的问题
2.1.定义目标对象
此步骤包括两个问题:1.定义哪些对象可以被序列化; 2.定义对象的哪些字段可以被序列化
假设我们要实现一个自定义协议,报文和通信部分都要自己完成. 那么其实报文的组装和解析就是一个序列化/反序列化的过程
此时,比较简单的实现,就是让需要序列化的对象实现以下接口
interface ICode_Decode {
byte[] serialize(object o);
Objcec deSerialize(byte[] bytes);
}
这种解决方式对于个性化的序列化要求比较适用,但是对于通用的序列化则不太现实,因为不可能让所有需要序列化的对象都实现一遍这两个方法.
所谓通用的序列化,就是把对象理解为由一系列属性名--属性值组成的Key--Value对.
①JDK和.net Framework对于对象的序列化都有其内部的实现。大致的实现方式都是通过接口或者特性来对类及其字段进行标注,然后进行序列化,因为都是自带的内部实现,因此这些实现对类本身的特性很熟悉,序列化时会有各自语言特有的内容。
②跨平台的XML和json序列化实现。
③根据配置文件生成类。即Protocol Buffers的实现。
syntax = "proto3";
package mypackname;
option java_package "org.feng.wildland";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
Corpus corpus = 4;
}
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
以上文件即为.proto的一个示例,通过代码生成工具,将会生成 org.feng.wildland.mypackagename.SearchRequest的类,并生成相应的用于序列化的方法。
2.2编码方式
①如XML和Json,字符串的编码方式
②二进制的编码方式
通常生成的json字符串是自包含的。但是pb不是。
pb序列化后的数据中不包括变量名,而只有变量编号,即.proto文件中每个变量后面定义的数字
pb编码后,第一个字节包括变量编号+变量类型,后面是变量的值;如果变量类型为不定长的类型,那么第二个字节是变量长度。
2.3版本号问题
我们的代码时不断迭代更新的,那么为对象添加删除字段也是很正常的事情。
①java中需要序列化的类需要添加private static final long serialVersionUID ,如果反序列化时,发现该字段不一致,则报错,如果该字段一致,但是新添了字段,那么该字段设置为默认值;
@Protocol Buffers中,没有 版本号的概念。在更新了代码后,再反序列化,会遇到以下情况
如果新添了字段,则该字段为默认值;如果新添了repeat 类型字段,则为空
如果删除了字段,则为不可识别的字段
最后
以上就是儒雅犀牛为你收集整理的GRPC从使用到深入--Protocol Buffers的理解一.Protocol Buffers应用场景的全部内容,希望文章能够帮你解决GRPC从使用到深入--Protocol Buffers的理解一.Protocol Buffers应用场景所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复