这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。
前言 以往的前后端分离项目中,数据通信都是使用的JSON格式进行传递,但是最近接触到了protobuf这一新格式,有着众多优势,值得学习。通过这篇笔记记录一下学习protobuf的安装和基础使用的过程。
1 什么是protobuf
protobuf(Protocol Buffers),是Google公司开发的一种轻便高效的结构化数据存储格式,并且与语言、平台无关,可扩展、可序列化。protobuf 是以二进制方式存储的,占用空间小,性能和效率大幅度优于 JSON、XML 等其他的结构化数据格式,但由于是二进制格式存储的,具有可读性较差的缺点。protobuf 在通信协议和数据存储等领域应用广泛。
2 配置使用环境
想要使用protobuf,需要编写要存储的数据结构的.proto描述。该描述文件需要通过protobuf编译器进行编译,因此我们首先需要下载protoc编译器。
2.1 下载protoc编译器
我们可以在github官方仓库(github.com/protocolbuf…)中找到编译器的安装教程。
根据官方文档,我们了解到protoc编译器是使用C++语言编写的。想要安装该编译器,可以通过两种方式:(1)下载项目源码,通过C++编译环境进行源码编译;(2)在release(github.com/protocolbuf…)下载官方提供的预先编译好的版本。第一个方法比较麻烦,可以参考官方文档(github.com/protocolbuf…)自行实践。下面主要描述第二种安装方式:
截至笔记编写时间,最新的发布版本是v3.20.1。由于我使用的是M1 Mac,因此下载该版本protoc-3.20.1-osx-aarch_64.zip。读者可根据自己电脑配置,选择适合的版本进行下载。
2.2 配置环境变量
根据2.1的步骤下载得到的是一个zip压缩文件,将其直接解压并放置在合适位置,下一步需要配置环境变量,指向该文件。网络上有关如何在macOS系统中配置环境变量的文章较多,在此不再赘述。我将文件放置在~/下,因此应该修改.zshrc文件,在末尾添加如下内容:
export PATH="$PATH:/Users/eamon/protoc-3.20.1-osx-aarch_64/bin"
保存并退出后,记得执行如下命令,使配置生效。
source ~/.zshrc
注:使用bash的,可以自行查阅相关资料进行设置。
设置好环境变量以后,我们可以执行如下命令查看protoc版本,验证是否安装成功。
protoc -version
可以看到正常显示了版本,因此安装成功。
2.3 安装protoc-gen-go
除了上面编译器的安装,我们还需要安装protoc-gen-go插件才能使编译器编译生成go代码,通过如下命令即可安装:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
⚠️避坑指南:
(1)在查阅网上资料时,浏览到的很多文章都会写安装该插件应执行如下命令:
go get -u github.com/golang/protobuf/protoc-gen-go
那你将得到如下报错:
go: module github.com/golang/protobuf is deprecated: Use the "google.golang.org/protobuf" module instead.
错误提示指明该插件已经迁移到了新的地址,而且注意要使用install而不是get,否则无法正确安装。
总之,执行我上面提供的命令即可。此外,记得将$GOPATH/bin加入环境变量,方法同上。
3 定义数据结构
protobuf的数据结构都是通过.proto文件进行定义的,然后使用protoc编译成相应的语言,下面通过一个简单示例来进行说明。
首先创建一个video.proto文件,内容如下:
syntax = "proto2";
package main;
message Video {
required int64 id = 1; // 视频唯一表示
required string author = 2; // 视频作者信息
required string play_url = 3; // 视频播放地址
required string cover_url = 4; // 视频封面地址
required int64 favorite_count = 5; // 视频的点赞总数
required int64 comment_count = 6; // 视频的评论总数
required bool is_favorite = 7; // true-已点赞,false-未点赞
}
- 第一行指定了proto版本,如果省略,编译器默认使用proto2语法,但为了显式声明避免一些错误,建议不要省略。
- 第二行声明了包名,防止不同消息类型有命名冲突。
- 消息类型使用
message关键字定义,Video 是类型名,id、author、play_url等则是该消息的各个字段。 .proto文件可以添加注释,注释格式与C语言相同,单行注释使用//,多行注释使用/**/。
注:具体的定义格式,可参考文末提供的学习资料,也可以查看官方文档,在此不进行详细说明。
4 编译.proto文件
如果正确完成了上述所有操作,那么只需要在文件目录下,执行如下命令即可:?
protoc --go_out=. video.proto
--go_out参数指明生成文件存放的路径,这里是使用.即当前路径下video.proto即需要编译的文件
⚠️执行完命令,大概率你并不会得到生成的go文件,而是得到如下报错:
protoc-gen-go: unable to determine Go import path for "video.proto"
Please specify either:
• a "go_package" option in the .proto source file, or
• a "M" argument on the command line.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.
--go_out: protoc-gen-go: Plugin failed with status code 1.
我们只需要在video.proto文件中加上:
option go_package=".";
整体文件如下:
syntax = "proto2";
package main;
option go_package=".";
message Video {
required int64 id = 1; // 视频唯一表示
required string author = 2; // 视频作者信息
required string play_url = 3; // 视频播放地址
required string cover_url = 4; // 视频封面地址
required int64 favorite_count = 5; // 视频的点赞总数
required int64 comment_count = 6; // 视频的评论总数
required bool is_favorite = 7; // true-已点赞,false-未点赞
}
至此,再次执行编译命令,就可以获得生成的go文件:
看到这里,恭喜你已经完成了使用protobuf的第一步!
参考及学习资料
- Go Protobuf简明教程(geektutu.com/post/quick-…)
- 在Go中使用Protobuf(www.jianshu.com/p/9a1fb2495…)
- Protobuf语言指南(zhuanlan.zhihu.com/p/82604466)
- protoc-gen-go 安装踩坑记录(blog.csdn.net/m0_52649917…)