01-ProtoBuf 使用和分析
本文主要记录了 Protobuf 的基本使用。包括 编译器 protoc 、Go Plugins 安装及 .proto文件定义、编译等。
原文作者: 意琦行
1. 概述
Protocol buffers 是一种语言无关、平台无关的可扩展机制或者说是数据交换格式,用于序列化结构化数据。与 XML、JSON 相比,Protocol buffers 序列化后的码流更小、速度更快、操作更简单。ProtoBuf是二进制的,更快更高效。
Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.
2. Protocol Compiler
protoc 用于编译 protocolbuf (.proto文件) 和 protobuf 运行时。
protoc 是 C++ 写的,比较简单的安装方式是直接下载编译好的二进制文件。
release 版本下载地址如下
|
|
下载操作系统对应版本然后解压然后配置一下环境变量即可。
比如windows
就下载protoc-3.20.0-win64.zip
然后把解压后的xxx\protoc-3.20.0-win64\bin
配置到环境变量。
linux
则下载protoc-3.20.0-linux-x86_64.zip
解压
|
|
新增环境变量
|
|
增加如下内容
|
|
使其生效
|
|
查看是否安装成功
|
|
3. Go Plugins
除了安装 protoc 之外还需要安装各个语言对应的编译插件,我用的 Go 语言,所以还需要安装一个 Go 语言的编译插件。它增强了protoc
编译器,使其知道如何 为给定.proto
文件生成 Go 特定代码。
|
|
4. Demo
创建.proto 文件
hello_world.proto
|
|
protocol buffer language 的 package 概念和go语言中的概念不太吻合。因此增加了一个go_package 的选项,定义了go包文件的导入路径,路径的最后一个部分,将成为go package的名称。
protoc 编译
编译命令
|
|
这里简单介绍一下 golang 的编译姿势:
–proto_path或者
-I
:指定 import 路径,可以指定多个参数,编译时按顺序查找,不指定时默认查找当前目录。- .proto 文件中也可以引入其他 .proto 文件,这里主要用于指定被引入文件的位置。
–go_out:golang编译支持,指定输出文件路径
- 其他语言则替换即可,比如
--java_out
等等
- 其他语言则替换即可,比如
–go_opt:指定参数,比如
--go_opt=paths=source_relative
就是表明生成文件输出使用相对路径。path/to/file.proto :被编译的 .proto 文件放在最后面
|
|
编译后会生成一个hello_word.pb.go
文件。
到此为止就ok了。
5. 编译过程
可以把 protoc 的编译过程分成简单的两个步骤:
- 解析 .proto 文件,编译成 protobuf 的原生数据结构保存在内存中;
- 把 protobuf 相关的数据结构传递给相应语言的编译插件,由插件负责将接收到的 protobuf 原生结构渲染输出为特定语言的模板。
具体过程如图所示:
protoc 中原生包含了部分语言(java、php、python、ruby等等)的编译插件,但是没有 Go 语言的,所以需要额外安装一个插件。
具体原生支持见源码
https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/compiler/main.cc
同样的,后续讲到的 gRPC Plugins、gRPC-Gateway 也是一个个的 protoc 编译插件,将 .proto 文件编译成对应模块需要的源文件。
6. 参考
https://developers.google.com/protocol-buffers
https://github.com/protocolbuffers/protobuf
https://studygolang.com/articles/12673
- 原文作者:长亭远望
- 原文链接:https://www.lvmo.work/2022/04/20/gpc-protobuf.html
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。