一、protobuf的安装和入门
1、mac环境下protobuf的安装
- 1.安装google protocol buffer 编译器,点击这里下载合适的压缩包。
- 2.安装golang protobuf,点击这里下载压缩包。
- 3.将下载后的protobuf编译器解压后,将bin目录下的可执行文件protoc复制到$GOPATH/bin目录下。
- 4.解压golang的protobuf,将整个protobuf移动到
$GOROOT/src/github.com/golang
目录下,没有的目录就新建。然后make
、make install
进行编译,将编译的protoc-gen-go
复制到$GOPATH/bin目录下。
2、把.proto文件生成一个.pb.go文件
下面的命令的含义是,将当前目录下的所有proto格式的文件都通过protoc生成为.pb.go格式的文件,并且生成的文件放置在当前目录下。
--go_out
右边的第一个路径就是生成文件需要放置的路径,第二个就是原始proto文件的路径。
protoc --go_out=./ *.proto
3、生成.pb.go文件后的简单使用
对于proto格式的message来说,比较常用和重要的就是序列化和反序列化的过程。
序列化:
msgBytes, err := proto.Marshal(pbmessage)
实参是任意定义格式的proto结构的message,返回的第一个结果是序列化后的[]byte数组,第二个结果的error(序列化失败会不为空)。
反序列化:
err := proto.Unmarshal(msgBytes, pbStructMsg)
第一个实参是需要反序列化的[]byte数组,第二个实参是反序列化后data存放的结构位置,返回error(反序列化失败会不为空),这里当然要注意,需要反序列化的数据需要和目标结构一致,不然无法正常反序列化。
4、使用protobuf替代json的总结
花了一段时间,重构了一个golang开发组件,将原本json的数据传输格式转换为protobuf。总体来说,使用protobuf的工作量是比使用json要大得多,而且一些复杂嵌套的结构,需要的赋值给struct的过程和代码都比json的复杂。[]byte格式的proto数据需要先反序列为proto结构的数据,然后struct定义的字段需要一个一个赋值。而json直接可以通过Unmarshal(),直接将[]byte格式的json数据反序列到指定的struct格式的数据。
但有舍就有得,工作量增加的protobuf传输格式,在传输效率上要远远高于json。一个不够成熟的理解,一种精细化操作的过程在工作上肯定比有概括能力的操作更加高效,当然在操作的准备过程会有一定额外的准备工作。
所以基类的出现方便扩展和解耦,而一些已知的具体工作(比如组件双方的数据传输结构),在已知的情况下,就应该更加向下细化而不是向上粗粒化。这样才是避免过度使用基类的正确思路,如此也正是protobuf能崛起的原因。
二、使用protobuf遇到的坑
1.“undefined: proto.InternalMessageInfo”
在实际运行的时候,遇到过这样的错误,具体的原因是因为proto.InternalMessageInfo
是在新版本的protobuf
才存在的一个结构,所以是因为旧版本的protobuf
导致的问题。重新拉一下新版本的protobuf
就可以了。
go get -u github.com/golang/protobuf/proto