[TOC] [protocol-buffers](https://developers.google.com/protocol-buffers) ## 简述 1. 一种数据交换格式 2. 相对字符传递可节省一半左右流量 ``` message Person { string name = 1; int32 id = 2; repeated string email = 3; } ``` 相当于把 `name `等 `key` 换为数字进行传输 3. 他既可以用作client/server 之间的数据交互,也可以用作 rpc 即可 grpc 4. protobuf 会有粘包问题,解决办法是在转为字节后,再添加到字节头部 ``` // 一个 golang 的例子 func main() { msg := &protogo.Msg{To: "hello", From: "word"} // 序列化为 bytes byt, _ := proto.Marshal(msg) //把字节长度转为字节放入头部 b :=IntToBytes(len(byt)) byt =append(b,byt...) log.Printf("len %v , content %v",len(a),a) // len 19 , content [0 17 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1] } func IntToBytes(n int) []byte { x := uint16(n)//定义包头长度为 2 个字节 bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, x) return bytesBuffer.Bytes() } ``` ### 快速入门 ``` msg := &protogo.Msg{To: "hello", From: "word"} // 序列化为 bytes bytes, e := proto.Marshal(msg) if e != nil { panic(bytes) } //反序列化为结构体 msg2 :=&protogo.Msg{} e = proto.Unmarshal(bytes, msg2) if e != nil { panic(e) } fmt.Printf("%+v\n", msg2) ``` ## 安装 ### 方案一 protobuf `go get github.com/golang/protobuf/protoc-gen-go ` 生成go文件 `protoc --go_out=. *.proto` ### gogo库 gogo库基于官方库开发,增加了很多的功能,包括: * 快速的序列化和反序列化 * 更规范的Go数据结构 * goprotobuf兼容 * 可选择的产生一些辅助方法,减少使用中的代码输入 * 可以选择产生测试代码和benchmark代码 * 其它序列化格式 * gogo同样支持grpc: protoc --gofast_out=plugins=grpc:. my.proto #### gofast 速度优先 不支持其它gogoprotobuf extensions。 ``` go get github.com/gogo/protobuf/protoc-gen-gofast protoc --gofast_out=. myproto.proto ``` #### gogofast、gogofaster、gogoslick 更快的速度、更多的产生代码 - gogofast类似gofast,但是会导入gogoprotobuf. - gogofaster类似gogofast, 不会产生XXX_unrecognized指针字段,可以减少垃圾回收时间。 - gogoslick类似gogofaster,但是可以增加一些额外的方法gostring和equal等等 ``` go get github.com/gogo/protobuf/proto //binary = protoc-gen-gogofast、protoc-gen-gogofaster 、protoc-gen-gogoslick go get github.com/gogo/protobuf/{binary} go get github.com/gogo/protobuf/gogoproto protoc -I=. -I=$GOPATH/src -I=$GOPATH/src/github.com/gogo/protobuf/protobuf --{binary}_out=. myproto.proto ``` #### protoc-gen-gogo ``` go get github.com/gogo/protobuf/proto go get github.com/gogo/protobuf/jsonpb go get github.com/gogo/protobuf/protoc-gen-gogo go get github.com/gogo/protobuf/gogoproto ```