protobuf是什么
Protocol Buffer是google 的一种数据交换的格式
独立于语言 独立于平台
google 提供多种语言的实现java、c#、c++、go 和 python
每一种实现都包含相应语言的编译器以及库文件
由于是二进制的格式 比用 xml 数据交换快
用于分布式应用之间的数据通信或异构环境下的数据交换
作为效率和兼容性都很优秀的二进制数据传输格式 用于诸如网络传输、配置文件、数据存储等诸多领域


什么是protoc
protoc是protobuf文件(.proto)的编译器 //github.com/google/protobuf
这个工具把 .proto 文件转译成各种编程语言对应的源码 包含数据类型定义 调用接口等


protoc编译过程示意图

通过查看protoc的源码//github.com/google/protobuf
可知 protoc 在设计上把protobuf和不同的语言解耦了 底层用c++来实现protobuf结构的存储 然后通过插件的形式来生成不同语言的源码
把protoc的编译过程分成简单的两个步骤
1)解析.proto文件 转译成protobuf的原生数据结构在内存中保存
2)把protobuf相关的数据结构传递给相应语言的编译插件 由插件负责根据接收到的protobuf原生结构渲染输出特定语言的模板


源码中//github.com/google/protobuf/blob/master/src/google/protobuf/compiler/main.cc
包含的插件有 csharp、java、js、objectivec、php、python、ruby等多种

protoc-gen-go是什么
protoc-gen-go是protobuf编译插件系列中的Go版本
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和go相关