Skip to content

Latest commit

 

History

History
167 lines (87 loc) · 7.29 KB

50.基础实战:protobuf协议的使用.md

File metadata and controls

167 lines (87 loc) · 7.29 KB

50 基础实战:protobuf协议的使用

什么是Protobuf协议

https://github.com/protocolbuffers/protobuf

Protobuf(Protocol Buffer)是Google提出的一种基于二进制数据交换格式,是一套类似JSON或者XML的数据传输格式和规范,用于不同应用或进程之间的通信。

Protobuf具有以下特点:

(1)语言无关,平台无关

Protobuf支持Java、C++、Python、JavaScript等多种语言,支持跨多个平台。

(2)高效

比XML更小(3-10倍)、更快(20-100倍)、更为简单。

(3)扩展性、兼容性好

可以更新数据结构,而不影响和破坏原有的旧程序。

Protobuf既独立于语言又独立于平台。Google官方提供了多种语言的实现:Java、C#、C++、GO、JavaScript和Python。

Protobuf的编码和解码

Protobuf的编码过程为:使用预先定义的Message数据结构将实际的传输数据进行打包,然后编码成二进制的码流进行传输或者存储。

Protobuf的解码过程刚好与编码过程相反:将二进制码流解码成Protobuf自己定义的Message结构的POJO实例。

与JSON、XML相比,Protobuf算是后起之秀,只是Protobuf更加适合于高性能、快速响应的数据传输应用场景

Protobuf数据包是一种二进制格式,相对于文本格式的数据交换(JSON、XML)来说,速度要快很多。Protobuf优异的性能使得它更加适用于分布式应用场景下的数据通信或者异构环境下的数据交换

Protobuf的优缺点

JSON、XML是文本格式,数据具有可读性;Protobuf是二进制数据格式,数据本身不具有可读性,只有反序列化之后才能得到真正可读的数据。正因为Protobuf是二进制数据格式,所以数据序列化之后体积相比JSON和XML要小,更加适合网络传输。

总体来说,在一个需要大量数据传输的应用场景中,数据量很大,选择Protobuf可以明显地减少传输的数据量和提升网络IO的速度。对于打造一款高性能的通信服务器来说,Protobuf传输协议是最高性能的传输协议之一。微信的消息传输就采用了Protobuf协议。

Protobuf协议的开发工作

  • 定义数据包格式的proto文件
  • proto数据包的序列化和反序列化的POJO和Builder

使用命令行生成POJO类

参见文章 👉

mac安装protobuf教程

SpringBoot集成protobuf实战

使用maven插件反向生成POJO类

工作原理和我们使用命令行生成是一样的,都需要借助我们之前下载的官方的工具。

<plugin>
	<groupId>org.xolstice.maven.plugins</groupId>
	<artifactId>protobuf-maven-plugin</artifactId>
	<version>0.5.0</version>
	<extensions>true</extensions>
	<configuration>
		<!--默认值-->
		<protoSourceRoot>${project.basedir}/proto/protoConfig</protoSourceRoot>
		<!--默认值-->
		<!--<outputDirectory>${project.build.directory}/generated-sources/protobuf/java</outputDirectory>-->
		<outputDirectory>${project.build.sourceDirectory}</outputDirectory>
		<!--设置是否在生成java文件之前清空outputDirectory的文件,默认值为true,设置为false时也会覆盖同名文件-->
		<clearOutputDirectory>false</clearOutputDirectory>
		<!--默认值-->
		<temporaryProtoFileDirectory>${project.build.directory}/protoc-temp</temporaryProtoFileDirectory>
		<!--更多配置信息可以查看https://www.xolstice.org/protobuf-maven-plugin/compile-mojo.html-->

		<protocExecutable>${project.basedir}/proto/protobin/protoc3.6.1.exe</protocExecutable>
	</configuration>
	<executions>
		<execution>
			<goals>
				<goal>compile</goal>
				<goal>test-compile</goal>
			</goals>

		</execution>
	</executions>
</plugin>

补充说明一下,

protoSourceRoot: 这个是我们定义的.proto文件的路径

outputDirectory: 这个是反向生成的java POJO类的路径

protocExecutable: 这个是我们本地安装的protoc的路径。虽然是通过maven编译器生成的,但是还是依赖我们本地安装的proto环境。

Protobuf协议规范

ProtocolBuffer提供了灵活、高效、自动化的方法来解决这些问题。通过ProtocolBuffer,只需要写一个 .proto 数据结构描述文件,就可以编译到几种语言的自动编码解码类。

生成的类提供了setter和getter方法来控制读写细节。最重要的是 ProtocolBuffer支持后期扩展协议,而又确保旧格式可以兼容。

protobuf的基本数值类型

更多

这个是官方的Protobuf协议规范 👇

How do Protocol Buffers Work?

When defining .proto files, you can specify that a field is either optional or repeated (proto2 and proto3) or singular (proto3). (The option to set a field to required is absent in proto3 and strongly discouraged in proto2. For more on this, see "Required is Forever" in Specifying Field Rules.)

After setting the optionality/repeatability of a field, you specify the data type. Protocol buffers support the usual primitive data types, such as integers, booleans, and floats. For the full list, see Scalar Value Types.

A field can also be of:

A message type, so that you can nest parts of the definition, such as for repeating sets of data. An enum type, so you can specify a set of values to choose from. A oneof type, which you can use when a message has many optional fields and at most one field will be set at the same time. A map type, to add key-value pairs to your definition. In proto2, messages can allow extensions to define fields outside of the message, itself. For example, the protobuf library's internal message schema allows extensions for custom, usage-specific options.

For more information about the options available, see the language guide for proto2 or proto3.

我们基本上都已经更新到proto3版本了,更多信息点击上面这个超链接即可到达,其实还是比较好理解的。

After setting optionality and field type, you assign a field number. Field numbers cannot be repurposed or reused. If you delete a field, you should reserve its field number to prevent someone from accidentally reusing the number.