Protobuf 在 Ubuntu18 下的安装和使用

Protocol Buffer 是 Google 搞的 RPC 服务的中间层数据协议。其实 RPC 服务之间可以用各种数据格式,例如 JSON、XML 等。但考虑编解码效率和传输效率的话,Protobuf 性能更好。

此外,Protobuf 还包含了一个编译器,可以把 proto 文件编译成各种语言对应的代码。

安装

下载源码

git clone https://github.com/protocolbuffers/protobuf.git

安装依赖库

Protocol Buffer 是 C++ 编写的,主要是安装 g++ 编译器:

sudo apt-get install autoconf automake libtool curl make g++ unzip

编译安装并更新共享库

cd protobuf/
./autogen.sh
./configure
make
sudo make install
sudo ldconfig

测试

protoc -h

安装 Golang 的 proto API

如果下载不了,可能需要配置代理,参考:https://blog.csdn.net/kikajack/article/details/105746603

每种语言在使用 Protobuf 时,通过调用现成的库来实现转换。Go 语言的 API 库安装方式:

// go get -v -u github.com/golang/protobuf/proto
// 已废弃,用下面的地址
go get -v -u  https://github.com/protocolbuffers/protobuf-go

因为 protocolbuffers 官方已经支持 Golang,所以此项目已经作废,请用官方的:https://github.com/protocolbuffers/protobuf-go

安装 Protobuf 的 protoc-get-go 插件

Protobuf 官方不支持自动生成 Go 代码,需要安装一个插件。从 github 下载后,编译为可执行文件,放到 /bin 目录下即可:

# 安装
// go get -v -u github.com/golang/protobuf/protoc-gen-go
// 已废弃,用下面的地址

迁移了,protocolbuffers 官方新地址在 protocolbuffers 项目下:

go get -v -u github.com/protocolbuffers/protobuf-go
# 编译
cd $GOPATH/src/github/golang/protobuf/protoc-gen-go
go build
# 放到 /bin 下
sudo cp protoc-gen-go /bin/

编译 proto 文件

假设当前目录下的 proto 文件名是 first.proto,执行下面命令:

protoc --go_out=. first.proto

得到 golang 代码 first.pb.go。proto 会在这个文件里自动创建 Go 语言的 struct,在项目中引入即可使用。

Protoc 基本语法

可以参考: https://colobu.com/2019/10/03/protobuf-ultimate-tutorial-in-go/

Protobuf 的使用流程:

  1. 编写 proto 文件
  2. 编译 proto 文件,得到各个语言的代码

推荐使用 proto3 语法,必须明确声明。如果没有声明,默认使用 proto2 语法。

消息 message

proto 文件由一个个具体的消息构成,包括请求消息和响应消息。每个消息则包含了各种类型的字段。

消息的每个字段包含前置的类型、字段名、Tag 标签。

每个字段前,可以加 repeated 关键字,表示该字段是数组。

syntax = "proto3";

// hello 请求
message HelloRequest {
	string name = 1;			// 姓名
	int32 age = 2;				// 年龄
	repeated string job = 3;	// 工作
}

message HelloResponse {
	int32 no = 1;
}

Tag

Tag 标签从 1 开始,定义后不可修改。[1-15]内的标识在编码时占用一个字节,包含标识和字段类型,对于常用字段最好放在前 15 个字段。

[19000-19999]之间的标识符是 proto 预留的,不可使用。

protoc 的编译结果

  • Go: 生成一个.pb.go文件,每个消息类型对应一个结构体
  • C++: 每个.proto文件生成一个.h文件和一个.cc文件,每个消息类型对应一个类
  • Java: 生成一个.java文件,同样每个消息对应一个类,同时还有一个特殊的Builder类用于创建消息接口

引入其他 proto 文件

import  "other.proto";

指定包名 package

项目太大时,难免有命名冲突。可以通过定义 proto 的包名避免 message 类型之间的名字冲突。

package foo.bar;

普通字段

保留字段和标签

可以使用 reserved 关键字指定保留字段名和标签。

message Foo {
    reserved 2, 15, 9 to 11;
    reserved "foo", "bar";
}

数据类型

除了基本数据类型外,proto 还支持复合数据类型,包括:枚举、map、数组、其它message。

.protoGo
doublefloat64
floatfloat32
int32int32
int64int64
uint32uint32
uint64uint64
sint32int32
sint64int64
fixed32uint32
fixed64uint64
sfixed32int32
sfixed64int64
boolbool
stringstring
bytes[]byte

Oneof

使用 Oneof 定义的一组字段,最多允许这组字段中的一个出现。

syntax = "proto3";
package abc;
message OneofMessage {
    oneof test_oneof {
      string name = 4;
      int64 value = 9;
    }
}

oneof 字段不能同时使用repeated。

map类型

proto3 的 map 语法为 map<key, value> map_name = fieldNumber,例如:

map<int64,string> m_name = 1;

枚举类型

枚举类型限定字段的值只能取某个特定的值,比如星期类型只能取周一到周日七个值。

枚举类型的定义采用C++ scoping规则,也就是枚举值是枚举类型的兄弟类型,而不是子类型,所以避免在同一个package定义重名的枚举字段。

嵌套类型

可以把 message 类型当做普通字段,嵌套使用。

message SearchResponse {
  message Result {
    string url = 1;
    string title = 2;
    repeated string snippets = 3;
  }
  repeated Result results = 1;
}
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值