Go 语言中使用 Protocol Buffers

张云飞Vir · · 890 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

0. 背景

当前流行微服务框架,gRPC和Protocol Buffers 是 Go 的微服务框架常用的框架。

1. Protocol Buffers 介绍

Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,很适合做数据存储或 RPC 数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。

总结下特点就是:

  • 它是一种序列化格式,和 JSON,XML 类似。
  • 它是二进制的,压缩比例高,短小。
  • 序列化处理速度很快
  • 非明文传输
  • 它通过一种 proto 语法描述格式,可以通过工具生成多种语言代码
  • 支持多种开发语言,Java,Go,Python,JS等

Github 地址:https://github.com/golang/protobuf

Protocol Buffers 通常用于 RPC (远程过程调用)过程中,比如微服务间通讯。

2. 开始之前

在开始之前,我们需要先安装和配置开发环境。

分两个步骤:

  • 安装 protoc 工具
  • 安装 protoc-gen-go

2.1 安装 protoc 工具

在下面这个网址里找到适合你系统的安装包。
https://github.com/protocolbuffers/protobuf/releases

我的机器是mac ,找到 protoc-3.11.4-osx-x86_64.zip 并下载。解压到文件后,修改环境变量。

解压后的文件里有 bin/protoc ,这个 protoc 命令用于编译和生成代码,后面会用到。

建议将这个文件位置放入到环境变量,以方便使用。比如在 修改 .bash_profile 文件,示例:

# PB 工具
export PB_PATH=/Users/zhangyunfei/chengxu/protoc-3.11.4-osx-x86_64
export PATH=$PATH:$PB_PATH/bin

2.2 安装 protoc-gen-go

protoc-gen-go 是 生成 Go 代码的 protocolbuffers 编译器。可以理解为一个编译器插件,配合 protoc 来使用。
在命令行中执行:

go get -u github.com/golang/protobuf/protoc-gen-go

这个工具用于生成 基于 Protocol Buffers 的代码。

3.开始使用

3.1 概述

使用步骤拆解:

  • (1) 定义.proto文件,它用来描述,定义传输过程中的数据包。
  • (2) 编译.proto文件,生成代码。用来将描述文件编译成指定平台的代码(比如生成GO源代码文件)。
  • (3) 获取特定平台的类库/包,用来在特定平台编码,解码等。

下面分别描述这几个步骤。

3.2 定义.proto文件

创建一个 model.proto 文件,它用来描述 数据包的内容,实体对象的字段等。
示例:

syntax = "proto2";
    package example;

    enum FOO { X = 17; };

    message Test {
      required string label = 1;
      optional int32 type = 2 [default=77];
      repeated int64 reps = 3;
    }

3.3 编译.proto文件

使用 protoc 生成 Go 源代码文件。

protoc --go_out=paths=source_relative:. model.proto

完成后,将生成的 Go 源代码文件放入项目中。

3.4 导入包和使用

导入包

import (
    "fmt"
    "github.com/golang/protobuf/proto"
)

序列化

  • 使用 proto.Marshal 来将 一个Go Struct 序列化成字节。-
  • 字节可以通过HTTP, Socket等网络传输。
  • 使用 proto.Unmarshal 来将 字节反序列化成对象。
package main

import (
    "fmt"
    "github.com/golang/protobuf/proto"
    example "gopbdemo/pb"
    "log"
)

func main() {
    // 一个实体
    obj := &example.Test{
        Label: proto.String("hello"),
        Type:  proto.Int32(17),
        Reps:  []int64{1, 2, 3},
    }
    // 序列化成字节
    data, err := proto.Marshal(obj)
    if err != nil {
        log.Fatal("序列化时发生错误: ", err)
    }
    fmt.Println("完成序列化,长度=", len(data))

    newObj := example.Test{}
    err = proto.Unmarshal(data, &newObj)
    if err != nil {
        log.Fatal("反序列化时发生错误: ", err)
    }
    fmt.Println("结果:", newObj.GetLabel(),newObj.GetType(),newObj.GetReps())

}

4. 参考

下载
https://github.com/protocolbuffers/protobuf/releases

协议
https://github.com/protocolbuffers/protobuf


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:张云飞Vir

查看原文:Go 语言中使用 Protocol Buffers

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

890 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传