Google Protobuf 编解码
更多内容,前往个人博客
Protobuf 全称:Google Protocol Buffers,由谷歌开源而来,经谷歌内部测试使用。它将数据结构以 .proto 文件进行描述,通过代码生成工具可以生成对应数据结构的 POJO 对象和 Protobuf 相关的方法和属性。
一、 Protocol 的特点
【1】在谷歌内部长期使用,产品成熟度高;
【2】高效的编解码性能,编码后的消息更小,有利于存储和传输;
【3】语言无关、平台无关、扩展性好
【4】官方支持 Java、C++ 、C#、 Python 、Go 和 Dart
Protobuf 使用二进制编码,在空间和性能上相对于 XML具有很大的优势。尽量 XML的可读性和可扩展性非常好,也非常适合描述数据结构,但是 XML 解析的时间开销和 XML为了可读性而牺牲的空间开销都非常大,因此不适合做高性能的通信协议。
Protobuf 的数据描述文件和代码生成机制(跨语言的编解码框架,都具有此功能),优点如下:
■ 文本化的数据结构描述语言,可以实现语言和平台无关,特别适合异构系统间的集成;
■ 通过标识字段的顺序,可以实现协议的前向兼容;
■ 自动代码生成,不需要手工编写同样数据结构的 C++ 和 Java 版本;
■ 方便后续的管理和维护。相当于代码,结构化的文档更容易管理和维护。
Protobuf 的编解码性能远远高于 JSON<Serializable<hession2<hession1<XStream<hession2压缩(性能有高到底)等序列化框架的序列化和反序列化,这也是很多 RPC 框架选用 protobuf 做编解码框架的原因。
二、Protobuf 开发环境搭建
【1】首先下载 Protobuf 的最新 Windown 版本:网站地址如下:https://github.com/protocolbuffers/protobuf/releases/tag/v3.9.1
官网对 java 编写 .proto 文件,详细说明地址:https://developers.google.cn/protocol-buffers/docs/javatutorial
下面我们定义一个 person.proto 数据文件。如下: 注释写在#号后,实际不能这么操作。此处为方便理解:
【2】通过 protoc.exe 命令行生成 Java 代码,命令如下:[ --java_out=生成 *.java 文件的存放路径,我所在的目录正是存放person.proto 文件的目录 ]没有任何错误就说明生成成功。
【3】查看生成的目标文件:或者在外面生成好,拷贝进来也行。建议不要对生成的文件做任何修改。我们发现代码编译出错,原因是因为少了 protobuf 的 jar 包:
引入 protobuf-java 相关的 jar 包,如下:
到此为止,Protobuf 开发环境已经搭建完毕,接下来进行示例展示。
三、Protobuf 编解码开发
Protobuf 的类库使用比较简单,下面通过对 AddressBookProtos 编解码来介绍 Protobuf 的使用:由于 Protobuf 支持复杂 POJO 对象编解码,所以代码都是通过工具自动生成,相比于传统的 POJO 对象的赋值操作,其使用略微复杂一些。Protobuf 的编解码接口非常简单和实用,但是功能和性能却非常强大,这也是它流行的一个重要原因。
四、Netty 的 Protobuf 服务端开发
【1】标准的服务端:主要区别在于 childHandler 方法中的 PersonChannelInitializer 类的内容。
【2】PersonChannelInitializer 内容展示:重点关注自定义 handler(PersonHandler)
【1】客户端:主要区别在于 childHandler 方法中的 PersonClientInitializer 类的内容。
启动服务端——>启动客户端,运行结果如下:
【1】服务端结果展示:
【2】客户端结果展示:
七、问题
当 .proto 中存在多个 message 时,在解码 ProtobufDecode(目标对象)中,添加的目标对象不唯一,会根据情况进行变化的问题及解决方案。
【1】.proto 文件内容如下:包含多个 message 对象。oneof 关键字表示:多个可选项,但允许选择一个。设置的新值会替换掉旧值。