定義
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/