protobuf初探筆記 - golang

認識protobuf

官網:https://developers.google.com/protocol-buffers

protobuf是google 的一種二進制數據交換的格式,類似於 json, xml等也是一種數據格式,是一個語言無關、平臺無關的數據序列化工具。簡單來說,如果客戶端和服務端使用的是不同的語言,那麼在服務端定義一個數據結構,通過protobuf轉化爲字節流,再傳送到客戶端解碼,就可以得到對應的數據結構。

在一些場景下,數據需要在不同的平臺,不同的程序中進行傳輸和使用,例如某個消息是用Java程序編寫的的,而另一個程序是用golang寫的,當前者產生一個消息數據時,需要在不同的語言編寫的不同的程序中進行操作,我們常用的就有json和xml,但
protobuf序列化和反序列的性能都是比較高的,protobuf序列化後的數據體積更小”。

安裝 protobuf 編譯插件

默認已經安裝go環境和brew

  1. protoc的安裝:
    命令行執行:
brew install protobuf@3.7

安裝完成之後執行:protoc --version 查看是否安裝成功以及版本號

protoc --version

如下圖顯示內容,即爲安裝成功。
在這裏插入圖片描述

  1. protoc-gen-go插件的安裝(將protobuf的的代碼轉換成go語言代碼的一個插件):

命令行執行

go get github.com/golang/protobuf/protoc-gen-go@v1.3.2
  1. protoc-gen-micro插件的安裝:

Go Micro默認使用protobuf作爲通信協議的定義,故需要安裝protoc-gen-micro來生成服務的接口代碼,這樣省去了很多重複的編碼工作,同時也保證了代碼的準確性。protoc-gen-micro依賴於protoc和protoc-gen-go

命令行執行

go get github.com/micro/protoc-gen-micro@v1.0.0

一個簡單的例子-protobuf的使用

目錄結構:

在這裏插入圖片描述

定義.proto文件

//.proto文件的第一行(syntax = "proto3";)指定了使用proto3語法。如果省略protocol buffer編譯器默認使用proto2語法。他必須是文件中非空非註釋行的第一行
syntax = "proto3”;
package proto;

import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

//message是protobuf語法中的一個關鍵字,相當於golang編程語言中的結構體struct,相當於C++中的類。

message SendMessage {
 MessageMeta meta = 1;
 string Body = 2;
}

message MessageMeta {
 google.protobuf.Duration ttr = 1;
 google.protobuf.Timestamp timestamp = 2;
 string routingKey = 3;
 map<string, string> header = 4;
}

編譯

進入到main.go所在目錄下,打開Terminal執行命令:

protoc -I=proto --go_out=./proto message.proto

將會生成 message.pb.go 文件。message.pb.go文件會自動放入proto文件夾(對應上面package)中

在golang代碼中使用protobuf中定義的內容

package main
import (
	"fmt"
	stProto "./examples/proto"
	"github.com/golang/protobuf/proto"
	"github.com/micro/go-micro/broker"
	"github.com/sirupsen/logrus"
	}
	
func main() {
.........初始化
	m := &stProto.SendMessage{
		Meta: &stProto.MessageMeta{
			Ttr:        ptypes.DurationProto(10 * time.Minute),
			Timestamp:  ptypes.TimestampNow(),
			RoutingKey: "micro.email.send",
			Header:     map[string]string{},
		},
		Body:   *proto.String("test send message by protobuf"),
	}
	encoded, err := proto.Marshal(m)
	if err != nil {
		fmt.Printf("Encode to protobuf data error: %v", err)
	}
	...........
	//初始化pb結構體對象,並讀取到pb結構體中
	msg := &stProto.SendMessage{}
	pbErr := proto.Unmarshal(encoded, msg) //反序列化數據
	............

	}
)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章