Protobuf简介

Protobuf是Protocol Buffers的简称,由Google公司开发的一种数据描述语言,用于描述一种轻便高效的结构化数据存储格式,它可用于结构化数据串行化,或者说序列化。它的设计非常适用于在网络通讯中的数据载体,很适合做数据存储或 RPC 数据交换格式,它序列化出来的数据量少再加上以 K-V 的方式来存储数据,对消息的版本兼容性非常强,可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。开发者可以通过Protobuf附带的工具生成代码并实现将结构化数据序列化的功能。

Protobuf中最基本的数据单元是message,是类似Go语言中结构体的存在。在message中可以嵌套message或其它的基础数据类型的成员。

protoc安装

https://github.com/google/protobuf/releases 下载对应的buf,然后进行编译后,使用 protoc --version 能查看对应版本,说明安装成功。

环境变量配置

第一步:if zsh vim ~/.zshrc; if bash vim ~/.bash_profile

1
2
3
export GOPATH="/Users/zl/go"
export GOBIN="/Users/zl/go/bin"
export PATH="$PATH:$GOPATH:$GOBIN"

第二步:source ~/.zshrc || source ~/.bash_profile

第三步: 查看环境变量

1
echo $PATH

注意: 以上配置具体路径 GOPATHGOBIN 根实际填写即可,可使用go env查看。

编译器

Protobuf核心的工具集是C++语言开发的,官方的protoc编译器中并不支持Go语言,需要安装插件才能生成Go代码。用如下命令安装:

1
go get github.com/golang/protobuf/protoc-gen-go

它提供了一个 protoc-gen-go 二进制文件,当编译器调用时传递了--go_out 命令行标志时 protoc 就会使用它。–go_out代表输出的扩展名为 .pb.go 的文件。编译器会为每个.proto文件生成一个单独的源代码文件。

注意: proto路径(使用–proto_path或-I命令行标志指定)将替换为输出路径(使用–go_out标志指定)。

扩展:

go-micro 是go语言中一个很好的微服务框架,功能完善。关于 micro 后面再做详细介绍。它也有个相对应的插件:

1
go get github.com/micro/protoc-gen-micro

定义proto文件

先在 proto 目录下新建一个 hello.proto 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
syntax = "proto3";
message HelloRequest {
string name = 1;
}
message HelloResponse {
string greeting = 1;
}
service Greeter {
rpc Hello(HelloRequest) returns (HelloResponse) {}
}

生成原型

1
protoc --proto_path=. --go_out=. */*.proto

编译器会读取proto目录下所有后缀名为 .proto的文件,这将会生成一个输出文件 product.pb.go

默认规则

如果一个.proto文件中有包声明,生成的源代码将会使用它来作为Go的包名,如果.proto的包名中有 . 在Go包名中会将 . 转换为 _。举例来说proto包名 example.hello 将会生成Go包名example_hello

指定包名

在.proto文件中可以使用option go_package 指令来覆盖上面默认生成Go包名的规则。比如说包含如下指令的一个.proto文件:

1
2
package example.hello;
option go_package = "proto;hello";

"proto;hello":proto表示目录,hello 则是生成的Go源代码的包名是。

不指定包名

如果一个.proto文件中不包含package声明,生成的源代码将会使用.proto文件的文件名(去掉扩展名)作为Go包名,.会被首先转换为_。如:hello.proto 文件默认生成源文件的包名为 hello

import其他proto