02.protobuf
# 01.protobuf安装
# 1.1 protobuf说明
为了实现跨语言调用,在golang中实现RPC方法的时候我们应该选择一种跨语言的数据编解码方式,比如JSON
上述的
jsonrpc
可以满足此要求,但是也存在一些缺点,比如不支持http传输,数据编解码性能不高等于是呢,一些第三方rpc库都选择采用
protobuf
进行数据编解码,并提供一些服务注册代码自动生成功能。Protobuf中最基本的
数据单元是message
,是类似Go语言中结构体
的存在。- 在message中可以嵌套message或其它的基础数据类型的成员。
# 1.2 安装protobuf
root@dev:opt# cd /opt
root@dev:opt# apt-get install libffi6=3.2.1-4 -y
root@dev:opt# sudo apt-get install autoconf automake libtool curl make g++ unzip libffi-dev -y
root@dev:opt# git clone https://github.com/protocolbuffers/protobuf.git
root@dev:protobuf# ./autogen.sh
root@dev:protobuf# ./configure
root@dev:protobuf# make && make install
root@dev:protobuf# sudo ldconfig
root@dev:protobuf# protoc -h
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 安装protobuf的go语言插件
# 1) 下载
root@dev:opt# cd /opt
root@dev:opt# export GOPROXY=https://goproxy.cn
root@dev:opt# go get -v -u github.com/golang/protobuf/proto
# 2) 进入到文件夹内进行编译
root@dev:opt# find / -name protoc-gen-go
root@dev:opt# cd /home/GOPATH/pkg/mod/github.com/golang/protobuf@v1.5.2/protoc-gen-go
root@dev:opt# go build
# 3)将生成的protoc-gen-go可执行文件,放在/bin目录下
root@dev:protoc-gen-go# cp protoc-gen-go /bin/
# 4)尝试补齐 protoc-gen-go
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 02.protobuf生成go文件格式
# 2.1 demo/pb/myproto.proto
// 采用proto3的语法(默认是 proto2)
syntax = "proto3";
option go_package = "./student";
// 指定所在包包名
package pb;
// 定义枚举类型
enum Week {
Monday = 0; // 枚举值,必须从 0 开始.
Turesday = 1;
}
// 定义消息体
message Student {
int32 age = 1; // 可以不从1开始, 但是不能重复. -- 不能使用 19000 - 19999
string name = 2;
People p = 3;
repeated int32 score = 4; // 数组
// 枚举
Week w = 5;
// 联合体
oneof data {
string teacher = 6;
string class = 7;
}
}
// 消息体可以嵌套
message People {
int32 weight = 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 2.2 myproto.pb.go
- 转成go语言格式
root@dev:db# protoc --go_out=./ *proto # 将所有.proto结尾的文件全部进行编译
root@dev:db# protoc --go_out=. myproto.proto # 指定对 myproto.proto进行编译
1
2
2
# 03.protobuf转json
# 3.1 db/class.proto
转成go语言格式
root@dev:db# protoc --go_out=. class.proto
1
// 默认是 proto2
syntax = "proto3";
option go_package = "./class";
// 指定所在包包名
package pb;
// 班级:定义消息体
message Class {
// 可以不从1开始, 但是不能重复. -- 不能使用 19000 - 19999
string class_name = 1;
Student stu = 2;
}
// 学生:消息体可以嵌套
message Student {
string name = 1;
int32 age = 2;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 3.2 db/class/class.pb.go
// 指定所在包包名
package class
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// 班级:定义消息体
type Class struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// 可以不从1开始, 但是不能重复. -- 不能使用 19000 - 19999
ClassName string `protobuf:"bytes,1,opt,name=class_name,json=className,proto3" json:"class_name,omitempty"`
Stu *Student `protobuf:"bytes,2,opt,name=stu,proto3" json:"stu,omitempty"`
}
// 学生:消息体可以嵌套
type Student struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Age int32 `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
}
func (x *Student) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Student) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 1.3 test-proto.go
package main
import (
"demo/db/class"
"encoding/json"
"fmt"
)
func main() {
cls := &class.Class{
ClassName: "golang学神班级",
Stu: &class.Student{
Name: "zhangsan",
Age: 23,
},
}
var s, _ = json.Marshal(cls)
jsonStr := string(s)
fmt.Println(jsonStr)
// {"class_name":"golang学神班级","stu":{"name":"zhangsan","age":23}}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
上次更新: 2024/3/13 15:35:10