Protobuf 介紹
序列化庫在網(wǎng)絡(luò)傳輸,RPC,數(shù)據(jù)庫訪問等環(huán)境中經(jīng)常用到,它的性能的好壞直接影響著整個產(chǎn)品的性能, 所以我們有必要對一些優(yōu)秀的序列化庫進(jìn)一步的學(xué)習(xí)與掌握.
protobuf是Google開發(fā)的一種數(shù)據(jù)描述語言語言,能夠?qū)⒔Y(jié)構(gòu)化的數(shù)據(jù)序列化,可用于數(shù)據(jù)存儲症虑,通信協(xié)議等方面,官方版本支持 Go, C++, Java, Python,社區(qū)版本支持更多語言.
相對于JSON和XML具有以下優(yōu)點:
簡潔
體積小:消息大小只需要XML的1/10 ~1?3
速度快:解析速度比XML快20 ~ 100倍
使用Protobuf的編譯器,可以生成更容易在編程中使用的數(shù)據(jù)訪問代碼
更好的兼容性,Protobuf設(shè)計的一個原則就是要能夠很好的支持向下或向上兼容
本文主要以Go語言的方式來具體講述如何使用Pb進(jìn)行數(shù)據(jù)的定義與傳輸
Protobuf 使用
安裝
1.從https://github.com/google/protobuf/releases獲取 Protobuf 編譯器 protoc
wgethttps://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gztar zxvf protobuf-2.6.1.tar.gzcdprotobuf-2.6.1./configuremakemakeinstallprotoc-h
2.獲取 goprotobuf 提供的 Protobuf 插件 protoc-gen-go(被放置于 $GOPATH/bin 下归薛,$GOPATH/bin 應(yīng)該被加入 PATH 環(huán)境變量谍憔,以便 protoc 能夠找到 protoc-gen-go)
此插件被 protoc 使用,用于編譯 .proto 文件為 Golang 源文件苟翻,通過此源文件可以使用定義在 .proto 文件中的消息韵卤。
go get github.com/golang/protobuf/protoc-gen-gocdgithub.com/golang/protobuf/protoc-gen-go go build goinstallvi/etc/profile 將$GOPATH/bin 加入環(huán)境變量sourceprofile
3.獲取 goprotobuf 提供的支持庫,包含諸如編碼(marshaling)崇猫、解碼(unmarshaling)等功能
go get github.com/golang/protobuf/protocdgithub.com/golang/protobuf/protogo buildgoinstall
使用 go protobuf
接著, 我們進(jìn)行數(shù)據(jù)格式的定義, 寫一個簡單的例子: 我們在 $GOPATH下新建一個測試項目 pblearn/packet 在 $GOPATH/pblearn/packet 下, 創(chuàng)建一個名為 packet.proto 的文件, 然后編寫如下的內(nèi)容
package packet;message Header{? ? required string messageId = 1;? ? required string topic = 2; //topic類型}//byte類消息message BytesMessage{? ? required Header? header= 1;? ? required? bytes body = 2;? ? }//string類型的messagemessage StringMessage{? ? required Header header = 1;? ? required string body = 2;}
然后通過 –go_out 來使用 goprotobuf 提供的 Protobuf 插件 protoc-gen-go沈条。這時候我們會生成一個名為 test.pb.go 的源文件, 參考如下
protoc--go_out=.*.proto
命令執(zhí)行后, pblearn/packet 下會生成一個go的文件 packet.pb.go, 這個就是我們消息操作對象
最后,我們可以編寫測試?yán)? 在 在 $GOPATH/pblearn/ 下,我們編寫 main.go
packagemainimport(// 輔助庫"github.com/golang/protobuf/proto"http:// test.pb.go 的路徑"pblearn/packet")funcmain(){bodyData:="guangzhou/fangcun/vip/company"p:=&packet.StringMessage{Body:proto.String(bodyData),Header:&packet.Header{MessageId:proto.String("20-05"),Topic:proto.String("golang"),},}pData,err:=proto.Marshal(p)iferr!=nil{println(err.Error())}println(string(pData))p2:=&packet.StringMessage{}proto.Unmarshal(pData,p2)println(p2.GetHeader().GetTopic())}
通過運(yùn)行例子 go run main.go 可以發(fā)現(xiàn), 我們的數(shù)據(jù)格式可以正常的序列化和反序列化了.
這樣,我們?nèi)蘸罂梢愿鶕?jù)自己的業(yè)務(wù)需要, 進(jìn)行高效的數(shù)據(jù)傳輸