protobuf与protoc-gen-go
from: https://studygolang.com/articles/12673?fr=sidebar
什么是protobuf
Protobuf(Protocol Buffer)是google 的一種數(shù)據(jù)交換的格式,它獨立于語言,獨立于平臺。google 提供了多種語言的實現(xiàn):java、c#、c++、go 和 python,每一種實現(xiàn)都包含了相應(yīng)語言的編譯器以及庫文件。由于它是一種二進制的格式,比使用 xml 進行數(shù)據(jù)交換快許多。可以把它用于分布式應(yīng)用之間的數(shù)據(jù)通信或者異構(gòu)環(huán)境下的數(shù)據(jù)交換。作為一種效率和兼容性都很優(yōu)秀的二進制數(shù)據(jù)傳輸格式,可以用于諸如網(wǎng)絡(luò)傳輸、配置文件、數(shù)據(jù)存儲等諸多領(lǐng)域。(參考鏈接)
什么是protoc
protoc是protobuf文件(.proto)的編譯器(參考鏈接),可以借助這個工具把 .proto 文件轉(zhuǎn)譯成各種編程語言對應(yīng)的源碼,包含數(shù)據(jù)類型定義、調(diào)用接口等。
通過查看protoc的源碼(參見github庫)可以知道,protoc在設(shè)計上把protobuf和不同的語言解耦了,底層用c++來實現(xiàn)protobuf結(jié)構(gòu)的存儲,然后通過插件的形式來生成不同語言的源碼。可以把protoc的編譯過程分成簡單的兩個步驟(如上圖所示):1)解析.proto文件,轉(zhuǎn)譯成protobuf的原生數(shù)據(jù)結(jié)構(gòu)在內(nèi)存中保存;2)把protobuf相關(guān)的數(shù)據(jù)結(jié)構(gòu)傳遞給相應(yīng)語言的編譯插件,由插件負(fù)責(zé)根據(jù)接收到的protobuf原生結(jié)構(gòu)渲染輸出特定語言的模板。
源碼中(參見github庫)包含的插件有 csharp、java、js、objectivec、php、python、ruby等多種。
什么是protoc-gen-go
protoc-gen-go是protobuf編譯插件系列中的Go版本。從上一小節(jié)知道原生的protoc并不包含Go版本的插件,不過可以在github上發(fā)現(xiàn)專門的代碼庫(參見github庫)。
由于protoc-gen-go是Go寫的,所以安裝它變得很簡單,只需要運行 go get -u github.com/golang/protobuf/protoc-gen-go,便可以在$GOPATH/bin目錄下發(fā)現(xiàn)這個工具。至此,就可以通過下面的命令來使用protoc-gen-go了。
protoc --go_out=output_directory input_directory/file.proto其中"--go_out="表示生成Go文件,protoc會自動尋找PATH(系統(tǒng)執(zhí)行路徑)中的protoc-gen-go執(zhí)行文件。
protoc-gen-go的源碼
按照Go的代碼風(fēng)格,protoc-gen-go源碼主要包含六個包(package):
main包
- doc.go 主要是說明。
- link_grpc.go 顯式引用protoc-gen-go/grpc包,觸發(fā)grpc的init函數(shù)。
- main.go 代碼不到50行,初始化generator,并調(diào)用generator相應(yīng)的方法輸出protobuf的Go語言文件。
generator包
- generator.go 包含了大部分由protobuf原生結(jié)構(gòu)到Go語言文件的渲染方法,其中 func (g *Generator) P(str ...interface{}) 這個方法會把渲染輸出到generator的output(generator匿名嵌套了bytes.Buffer,因此有Buffer的方法)。
- name_test.go 測試,主要包含generator中名稱相關(guān)方法的測試。
grpc包
- grpc.go 與generator相似,但是包含了很多生成grpc相關(guān)方法的方法,比如渲染轉(zhuǎn)譯protobuf中定義的rpc方法(在generator中不包含,其默認(rèn)不轉(zhuǎn)譯service的定義)
descriptor 包含protobuf的描述文件(.proto文件及其對應(yīng)的Go編譯文件),其中proto文件來自于proto庫(參見這里)
plugin 包含plugin的描述文件(.proto文件及其對應(yīng)的Go編譯文件),其中proto文件來自于proto庫,參見這里
結(jié)語
從巴別塔的傳說(參見這里)可以知道,欲要構(gòu)建大系統(tǒng),個體之間的溝通規(guī)范很重要。protobuf的出現(xiàn),為不同系統(tǒng)之間的連接提供了一種語言規(guī)范,只要遵循了這個規(guī)范,各個系統(tǒng)之間就是解耦的,非常適合近年來流行的微服務(wù)架構(gòu)。
如果吧protoc和protoc-gen-go看成兩個微服務(wù),可以發(fā)現(xiàn)這兩個服務(wù)就是完全解耦的;兩者完全負(fù)責(zé)不同的功能,可以分別編碼、升級,串接這兩個服務(wù)的就是proto規(guī)范。
總結(jié)
以上是生活随笔為你收集整理的protobuf与protoc-gen-go的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Git 工具 - 子模块 外部引用
- 下一篇: 超全机器学习术语词汇表