• Protocol buffer时间处理(golang)


    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 类型定义如下

    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.Timetimestamp.Timestamp来处理和传输时间戳,直接使用 int32int64来表示秒级时间戳,免去类型互相转换。

    生老病死过于平淡,唯有求知聊以慰藉。
  • 相关阅读:
    使用Redis的理由
    从输入网址到显示网页的全过程分析
    Node.js初识
    GET和POST的数据传递到底有何区别?
    第四五六周学习进度
    首尾相接整数数组中最大子数组的和
    网页版四则运算
    团队介绍及项目简介
    整数数组中最大子数组的和
    软件工程个人作业03
  • 原文地址:https://www.cnblogs.com/wangbs95/p/13878309.html
Copyright © 2020-2023  润新知