您的位置:

protobufgo:高效、灵活、跨语言的数据序列化与反序列化

一、protobuf构建

protobuf是一种轻量级、高效、平台无关、语言无关、扩展性强的数据序列化和反序列化协议。在protobuf中,开发者可以通过定义消息格式,自动生成数据访问API,从而达到数据传输和存储的目的。

protobufgo是Golang社区提供的一种开源工具,旨在为Golang开发者提供高效、灵活、跨语言的protobuf序列化和反序列化功能。使用protobufgo,我们可以方便地通过protobuf定义文件,生成Golang访问API,并且可以与其他语言的protobuf代码进行互操作。

我们可以通过以下步骤来构建protobufgo:

// 安装protobuf工具
$ go get github.com/golang/protobuf/proto

// 安装protobufgogo插件
$ go get github.com/gogo/protobuf/proto
$ go get github.com/gogo/protobuf/protoc-gen-gogo

二、protobuf工具

protobufgo提供了许多有用的工具,可以帮助我们更轻松地开发和维护代码。以下是一些常用的工具:

1. protoc

protoc是protobuf官方提供的编译器,负责将protobuf定义文件编译成不同语言的访问API。protobufgo通过gogo/protobuf插件对protoc进行了扩展,提供了更多的选项和功能,例如生成更快的序列化和反序列化方法、支持不同语言之间的互操作等。

2. protoc-gen-go

protoc-gen-go是protobuf官方提供的Golang插件,用于将protobuf定义文件编译成Golang访问API。protobufgo提供了gogo/protobuf插件,可以生成更高效的序列化和反序列化方法,也可以支持更多的选项和功能,例如生成google.golang.org/genproto包下的Golang protobuf代码。

3. protoc-gen-gofast

protoc-gen-gofast是protobufgo提供的一个更快的Golang插件,它基于gogo/protobuf插件进行了优化,生成的代码速度更快。

4. protoc-gen-grpc-gateway

protoc-gen-grpc-gateway是一个开源的grpc转换代理,可以将标准的grpc服务转换成RESTful的API接口,支持多种编程语言,包括Golang。

三、protobuf公参

protobuf定义文件定义了消息的结构和字段信息,类似于Golang中的struct,包括以下4个要素:

1. package

指定生成的代码所在的Golang代码包。

2. import

导入其他protobuf定义文件。

3. message

定义消息结构和字段信息。

4. service

定义服务器和客户端之间的远程调用接口。

以下是一个简单的protobuf定义文件的示例:

    syntax = "proto3";
    package example;
    
    import "google/protobuf/timestamp.proto";
    
    message Person {
        string name = 1;
        int32 age = 2;
        repeated string email = 3;
        google.protobuf.Timestamp created_time = 4;
    }
    
    service PersonService {
        rpc GetPerson (PersonRequest) returns (PersonResponse);
    }
    
    message PersonRequest {
        string name = 1;
    }
    
    message PersonResponse {
        Person person = 1;
    }

四、protobuf构建与移植

protobufgo提供了多种选项和调用方式,以满足不同平台和应用场景的需要。总体而言,protobufgo可以分为以下3个部分进行构建和移植:

1. protoc编译器

protoc编译器是protobufgo的核心,可以将protobuf定义文件编译成不同语言的访问API。protobufgo通过gogo/protobuf插件对protoc进行了扩展,提供了更多的选项和功能,例如生成更快的序列化和反序列化方法、支持不同语言之间的互操作等。以下是一些常用的命令:

// 编译proto文件
$ protoc --proto_path=$GOPATH/src:. --gogo_out=. file.proto

// 支持生成其他语言的代码,例如Java:
$ protoc --proto_path=$GOPATH/src:. --java_out=. file.proto

2. gogo/protobuf插件

gogo/protobuf插件是protobufgo提供的一种高效、灵活、跨语言的protobuf序列化和反序列化库。在Golang应用程序中使用protobufgo,需要先将protobuf定义文件编译成Golang访问API,然后将生成的代码导入到应用程序中。以下是一些常用的命令:

// 安装插件
$ go get github.com/gogo/protobuf/proto
$ go get github.com/gogo/protobuf/protoc-gen-gogo

// 编译proto文件
$ protoc --proto_path=$GOPATH/src:. --gogo_out=. file.proto

3. 应用程序

在应用程序中使用protobufgo,需要导入protobuf生成的Golang代码,并定义和使用消息结构体。

import "example/file.pb.go"

func main() {
    person := &example.Person{
        Name: "Tom",
        Age:  28,
        Email: []string{"tom@example.com", "tom@gmail.com"},
        CreatedTime: &timestamp.Timestamp{
            Seconds: time.Now().Unix(),
        },
    }
    data, _ := proto.Marshal(person)
    newPerson := &example.Person{}
    _ = proto.Unmarshal(data, newPerson)
}

五、protobuf共享内存

protobufgo支持将消息数组序列化到共享内存中,以实现进程之间的数据传递和共享。以下是一些常用的命令:

// 获取消息占用的共享内存大小
size := proto.Size(msg)

// 分配共享内存
shmID, err := ipc.ShmGet(1, size, ipc.IPC_CREAT|ipc.IPC_EXCL|0666)

// 将消息序列化到共享内存
msgBytes, err := proto.Marshal(msg)
shmbuf, err := ipc.Shmat(shmID, uintptr(0), 0)
copy((*((*[1 << 30]byte)(unsafe.Pointer(shmbuf))))[:size], msgBytes)
ipc.Shmdt(shmbuf)

// 从共享内存中反序列化消息
shmbuf, err = ipc.Shmat(shmID, uintptr(0), 0)
unmarshMsg := &T{}
_ = proto.Unmarshal(shmbuf[:size], unmarshMsg)
ipc.Shmdt(shmbuf)

六、protobuf工具转json

protobufgo支持将消息序列化为JSON字符串,以方便在HTTP API中传输和返回。以下是一些常用的命令:

// 将消息序列化为JSON字符串
buf, err := protojson.Marshal(msg)

// 将JSON字符串反序列化为消息
newMsg := &T{}
_ = protojson.Unmarshal(buf, newMsg)

上述代码片段中的T代表消息结构体。

七、总结

protobufgo是一种高效、灵活、跨语言的数据序列化和反序列化协议,提供了强大的命令工具和访问API,可以帮助我们更轻松地开发和维护代码。