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