Protocol buffer時間處理(golang)
阿新 • • 發佈:2020-10-26
Protocol buffer
protocol buffer 是一種資料傳輸協議,比 Json、xml 等效率更高。
準確的說 pb 是傳輸協議,而後兩者是序列化協議。
序列化協議有兩個屬性:
- 結構化程度(人類可讀性)
- 壓縮程度(序列化後的資料大小)
同一個物件序列化後,以上兩個屬性基本上是此消彼長、不可兼得的。因為要想人類可讀就必須是字串,且需要加入如{}[],以及換行符等符號做輔助,必然資料不能很好地壓縮。
因此,pb 相對於 Json、XML 結構化很差,但是壓縮程度很高,所以傳輸效率高。只不過人類程式設計師不需要去閱讀序列化後的資料文字,其定義了.proto檔案後直接生成客戶端、服務端程式碼,程式設計師在兩端都只需要關心程式中的物件(序列化前的物件和已反序列化後的物件)。
關於變數的處理
protocol buffer 本身是有時間戳的支援的,與 golang 可以融洽地結合。
實際大部分程式設計對時間的處理只需要精確到秒,也可以簡略一點,直接使用 int32 或 int64 傳輸時間戳。
Timestamp
在 .proto檔案中使用google.protobuf.Timestamp
型別定義時間:
syntax = "proto3"; package pb; import public "google/protobuf/timestamp.proto"; message person{ google.protobuf.Timestamp birthday = 1; }
對應生成的 .pb.go 檔案中型別為*timestamp.Timestamp
:
type Person struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Birthday *timestamp.Timestamp `protobuf:"bytes,1,opt,name=birthday,proto3" json:"birthday,omitempty"`
}
其中,timestamp.Timestamp
message Timestamp {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
int64 seconds = 1;
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
int32 nanos = 2;
}
go 語言 time.Time
型別與 timestamp.Timestamp
互相轉換使用github.com/golang/protobuf/ptypes
包下方法:
package pb
import (
"fmt"
"github.com/golang/protobuf/ptypes"
"time"
)
func TimeStampFeature() {
//Timestamp 轉 Time
//獲取的是系統時區的時間戳
pbTimestamp := ptypes.TimestampNow()
//此方法預設 UTC 時區
goTime, _ := ptypes.Timestamp(pbTimestamp)
//設定為系統時區
fmt.Println(goTime.Local())
//Time 轉 Timestamp
goTime2 := time.Now()
pbTimestamp2, _ := ptypes.TimestampProto(goTime2)
fmt.Println(pbTimestamp2)
}
輸出為:
=== RUN TestTimeStampFeature
2020-10-26 14:10:48.69129 +0800 CST
seconds:1603692648 nanos:691445000
--- PASS: TestTimeStampFeature (0.00s)
PASS
秒級時間戳
若只時間處理只精確到秒,則不必使用 time.Time
和timestamp.Timestamp
來處理和傳輸時間戳,直接使用 int32
或 int64
來表示秒級時間戳,免去型別互相轉換。