定义
developers.google.com 大概是这么定义的:一种用于通信协议、数据存储等用途,语言中立、平台中立的,可扩展的,对结构化数据进行序列化的方法。
Protocol buffers 是一种灵活、高效的自动化的序列化结构化数据的机制——对比 XML,其更小、更快、更简单。一次性定义好数据的结构,然后就可以生成一种特定的源码,轻松地使用各种语言在向多种数据流写入或从多种数据流读取结构化数据。
我翻得有些拗口。说白了就是一种数据格式,类似 JSON 和 XML,可以被多种语言序列化和反序列化。主要的有点就是小。重点是:它的老子的 Google。小的话通常就会快,但为什么小,怎么小的,以及真的更简单么,下面来看一看。以GO语言为例。
数据量
对于同一个结构体,看一下两种序列化结果的数据量。对象:
{
"Name": "xiaoming",
"Age": 18
}
json 序列化为字符串,字节数组为
[123 34 78 97 109 101 34 58 34 120 105 97 111 109 105 110 103 34 44 34 65 103 101 34 58 49 56 125]
其中[78 97 109 101]
是 Name,[120 105 97 111 109 105 110 103]
是 小明。
protocol buffers 序列化后的字节数组为
[10 8 120 105 97 111 109 105 110 103 16 18]
比 json 序列化后数据量小了,因为没有了 Name、Age 这些 schema。数据规模越大,序列化后数据量减少的优势将越明显。
更简单么
- 标准库有 json 包,序列化为json只要如下代码
type person struct {
Name string
Age int
}
xiaoming := person{
Name: "xiaoming",
Age: 18,
}
jsonBytes, err := json.Marshal(xiaoming)
- 要使用 protobuf,先安装包
go get -u github.com/golang/protobuf
编写person.proto文件
syntax="proto3";
package main;
message Person{
string name = 1;
int32 age = 2;
}
从 https://github.com/protocolbuffers/protobuf/releases 下载 protocol 编译器——protoc,我下载的是3.11.4-linux-x86_64版本,在 wsl 中执行。
编译 proto 文件,生成 person.pb.go 文件
protoc --go_out=. *.proto
序列化结构体
xiaoming := &Person{
Name: "xiaoming",
Age: 18,
}
protoBytes, err := proto.Marshal(xiaoming)
显然比 json 序列化要麻烦一些。
参考:
- https://developers.google.com/protocol-buffers/docs/overview
- https://tutorialedge.net/golang/go-protocol-buffer-tutorial/