微服务组件之proto
protobuf
-
和平台、语言无关的一种序列化的数据格式,适合用来做数据存储和作为不同语言、应用、平台之间相互通信的数据格式,只要实现proto的不同语言版本,加入不同的工程中,其他语言就可以解析出序列化的数据,官网目前提供C++、Python、Java、Go。08年开源。
-
格式对比
- json:一般的web项目中主要使用的是json,浏览器对json支持非常好,内建的函数支持。
- xml:在webservice中应用比较广泛,相比json会显得更加的荣誉,json使用键值对的方式,可以压缩空间,还有可读性。
- protobuf:后起之秀,google开源的数据格式,适合高性能,对响应速度有要求的数据传输场景,因为是二进制的所以不可读,只有反序列化之后才具有可读性。
- protobuf优势:
- 序列化之后体积更小
- 支持跨平台多语言
- 兼容性不错,消息格式升级
- 反序列化快
-
可以定义自己的数据结构然后使用代码生成器生成的代码来读写这个数据节,可以不用重新部署就可以更新数据结构。有良好的向后兼容的特性,不必破坏原有的老的数据格式就可以升级。但是,他有不足,无法表示复杂的概念,同时在通用性上可能不及xml等,protobuf不能被人直接读写。
安装Protobuf
- https://zhuanlan.zhihu.com/p/160249058
- 获取go的操作包,
go get -v -u github.com/golang/protobuf/proto
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang$ cd protobuf@v1.4.2/
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang/protobuf@v1.4.2$ ls
AUTHORS CONTRIBUTORS README.md go.mod internal proto ptypes test.bash
CONTRIBUTING.md LICENSE descriptor go.sum jsonpb protoc-gen-go regenerate.bash
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang/protobuf@v1.4.2$ cd protoc-gen-go/
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang/protobuf@v1.4.2/protoc-gen-go$ ls
descriptor generator grpc main.go plugin
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang/protobuf@v1.4.2/protoc-gen-go$ go build
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang/protobuf@v1.4.2/protoc-gen-go$ ls
descriptor generator grpc main.go plugin protoc-gen-go
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang/protobuf@v1.4.2/protoc-gen-go$ sudo cp protoc-gen-go /bin
et@ubuntu:~/Desktop/Projects/beego/unioj/pkg/mod/github.com/golang/protobuf@v1.4.2/protoc-gen-go$
- 编写proto文件
- proto文件会被转化对应语言的文件,对于go来说对每个消息生成一个.pd.go文件
protoc --go_out=./ *.proto
proto操作实例
-
目录结构
-
test.proto
syntax = "proto3" ;
//包名和文件夹一样
package protobuf ;
// 生成go文件命令:protoc --go_out=./ *.proto
message PandaRequest{
//1 2 3 代表的是对应字段的顺序而不是键值对
string name = 1 ;
repeated int32 weight = 2 ;
int32 height = 3 ;
string motto = 4;
}
- 执行命令生成对应的操作proto的go文件及test.pb.go
protoc --go_out=./ *.proto
- 使用测试
func TestProtoBuffer(t *testing.T){
text := &protobuf.PandaRequest{
Name: "panda",
Weight: []int32{100,101,103,104,120},
Height: 120,
Motto: "always head up high",
}
fmt.Println(text)
data,err := proto.Marshal(text)
if err != nil {
panic(err)
}
fmt.Println(data)
newPanda := &protobuf.PandaRequest{}
err = proto.Unmarshal(data, newPanda)
if err != nil {
return
}
fmt.Println(newPanda)
}
- 输出
/usr/local/bin/go tool test2json -t /tmp/GoLand/___TestProtoBuffer_in_unioj_utils_test.test -test.v -test.run ^\QTestProtoBuffer\E$
=== RUN TestProtoBuffer
name:"panda" weight:100 weight:101 weight:103 weight:104 weight:120 height:120 motto:"always head up high"
[10 5 112 97 110 100 97 18 5 100 101 103 104 120 24 120 34 19 97 108 119 97 121 115 32 104 101 97 100 32 117 112 32 104 105 103 104]
name:"panda" weight:100 weight:101 weight:103 weight:104 weight:120 height:120 motto:"always head up high"
--- PASS: TestProtoBuffer (0.00s)
PASS