一、protocal buffer 是什么?

一种序列化机制。

什么是序列化?

一种转化为可存储和传输对象的过程。

序列化的方式有很多,那么proto有什么特殊的呢?

它的英文介绍里提到了neutral这个词,中立,无关的。

language-neutral 跨语言:它可以应用于多种开发语言之间数据交互。

platform-neutral 跨平台:它可以运行于多种系统平台

可扩展

序列化过程性能优越,速度快

序列化后为二进制数据,相对的占用空间更小(存储成本及传输成本)及一定程度的保障数据的安全性。

提供支持多语言的自动化代码生成工具,开发易用性

二、下面以一个简单地示例开始:

proto3 文件:.proto

syntax = "proto3";

message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}

第一行声明当前使用的proto3版本协议语法(proto编译器默认使用proto2版本协议语法),声明必须为文件的第一行,此前不能有任何内容,包括注释。

消息使用“message”关键字定义,内部以“字段类型 字段名称 = 字段序号;”形式定义所要包含额属性。

1、序号:

每一个字段被赋予一个唯一的序号,起始为1不可重复。通常考虑到向后兼容的因素,不建议修改已定义的字段序号。

需要注意的是,序号大小会影响序列化编码的空间占用,例如:

序号范围[1,15]:proto使用1个字节存储字段的序号及类型,适宜定义常用字段。

序号范围 [16,2047]:proto使用2个字节存储字段的序号及类型。

...

序号可用域[1,229 - 1],其中[19000,19999]为proto保留序号范围(编译使用),不可使用。另外,开发方可以约定保留序号,以供扩展或其它特殊使用。

2、字段约束

singular:更直观的可以用optional来释义,可选字段,0个或1个,proto3中未默认约束。

repeated:列表集合字段类型,可以包含 >=0 个字段元素。

三、数据类型

proto3编码类型对应不同开发语言数据类型:

.proto Type 说明 Java Type
double   double
float   float
int32

使用可变长编码。

对于负数编码效率较低(可以使用sint32类型存储)

int
int64

使用可变长编码。

对于负数编码效率较低(可以使用sint64类型存储)

long
uint32 使用可变长编码。 int[1]
uint64 使用可变长编码。 long[1]
sint32 使用可变长编码,存储有符号整数。尤其对负数编码效率更高。 int
sint64

使用可变长编码,存储有符号整数。尤其对负数编码效率更高。

long
fixed32 四字节空间占用。存储值>228时,存储效率高于uint32。 int[1]
fixed64

八字节空间占用。存储值>256时,存储效率高于uint64。

long[1]
sfixed32 四字节空间占用 int
sfixed64 八字节空间占用 long
bool   boolean
string UTF-8编码或者7位ASCII文本,长度不可超过232 String
bytes 可以存储任何二进制数据,长度不可超过232 ByteString

四、默认值

singular 类型字段在进行编解码时,如果没有进行赋值则赋予默认值。不同类型使用默认值如下:

类型 默认值
string 空字符串
bytes 空byte数组
bool false
数值类型 0
enums 定义的枚举第一个元素(默认必须为0)
定义的message类型 不赋值
repeated * 空列表

proto3关于默认值的操作,在我们实际的使用中不免会造成一些困扰,我们需要去区分未知结果默认值结果两者之间的区别。例如,我们定义了bool类型字段updated(是否已更新),默认的false所表示未更新,则会将未知是否已更新覆盖。

对于此,通常处理的方式是引入包装类型wrapper,使用如下:

import "google/protobuf/wrappers.proto";

wappers.proto文件定义如下:

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Wrappers for primitive (non-message) types. These types are useful
// for embedding primitives in the `google.protobuf.Any` type and for places
// where we need to distinguish between the absence of a primitive
// typed field and its default value.
//
// These wrappers have no meaningful use within repeated fields as they lack
// the ability to detect presence on individual elements.
// These wrappers have no meaningful use within a map or a oneof since
// individual entries of a map or fields of a oneof can already detect presence. syntax = "proto3"; package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option go_package = "github.com/golang/protobuf/ptypes/wrappers";
option java_package = "com.google.protobuf";
option java_outer_classname = "WrappersProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB"; // Wrapper message for `double`.
//
// The JSON representation for `DoubleValue` is JSON number.
message DoubleValue {
// The double value.
double value = 1;
} // Wrapper message for `float`.
//
// The JSON representation for `FloatValue` is JSON number.
message FloatValue {
// The float value.
float value = 1;
} // Wrapper message for `int64`.
//
// The JSON representation for `Int64Value` is JSON string.
message Int64Value {
// The int64 value.
int64 value = 1;
} // Wrapper message for `uint64`.
//
// The JSON representation for `UInt64Value` is JSON string.
message UInt64Value {
// The uint64 value.
uint64 value = 1;
} // Wrapper message for `int32`.
//
// The JSON representation for `Int32Value` is JSON number.
message Int32Value {
// The int32 value.
int32 value = 1;
} // Wrapper message for `uint32`.
//
// The JSON representation for `UInt32Value` is JSON number.
message UInt32Value {
// The uint32 value.
uint32 value = 1;
} // Wrapper message for `bool`.
//
// The JSON representation for `BoolValue` is JSON `true` and `false`.
message BoolValue {
// The bool value.
bool value = 1;
} // Wrapper message for `string`.
//
// The JSON representation for `StringValue` is JSON string.
message StringValue {
// The string value.
string value = 1;
} // Wrapper message for `bytes`.
//
// The JSON representation for `BytesValue` is JSON string.
message BytesValue {
// The bytes value.
bytes value = 1;
}

五、枚举

enum 枚举对象 {

UNKOWN = 0; //默认值机制使用(首先必须有一个枚举值为0的枚举实例,其次兼容proto2中使用第一个变量为默认值的机制)

枚举实例 = 枚举值;

... ...

}

六、定义更新

1、不可修改已定义的字段序号。

2、可以删除已定义的字段,但是其序号不可在被使用。

3、int32, uint32, int64, uint64及bool是相互兼容的,只不过转换过程会产生值域变更

4、sint32 和 sint64 是相互兼容的。

5、byte3存储值为有效UTF-8编码内容时与string相互兼容。

七、未知字段

未能对应解析的字段会存储于未知字段中。此机制在proto3中最初抛弃,v3.5版本重新引入。

八、Map 类型

定义如下:

map<key_type, value_type> map_field = N。

key_type:任何整形或者string类型。

value_type:可以为除了Map类型外的任何类型。

proto3 协议指引的更多相关文章

  1. Golang使用proto3协议导致零值字段不显示

    Golang使用proto3协议导致零值字段不显示 问题描述 proto协议生成的结构体如果使用直接转成json会导致零值字段不显示,这样的json是有毛病的,可以使用如下方法解决 示例Demo pa ...

  2. Golang语言下使用Protocol Buffer教程

    代码仓库地址 一.介绍 Protobuf是Google旗下的一款平台无关,语言无关,可扩展的序列化结构数据格式.所以很适合用做数据存储和作为不同应用,不同语言之间相互通信的数据交换格式,只要实现相同的 ...

  3. .NET Core使用gRPC打造服务间通信基础设施

    一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制. 利用这种传输机制,不同进程(或服务)间像调用本地进程中 ...

  4. HTTP和RPC是现代微服务架构,HTTP和RPC是现代微服务架构

    .NET Core使用gRPC打造服务间通信基础设施   一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制 ...

  5. 使用gRPC打造服务间通信基础设施

    一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制. 利用这种传输机制,不同进程(或服务)间像调用本地进程中 ...

  6. protobuf3的学习笔记

    学习protobuf的过程中踩了不少的坑,这篇博文算是一个小结吧! 环境: windows VisualStudio Google.Protobuf.Tools. Google.Protobuf. 其 ...

  7. GO gRPC教程-环境安装(一)

    前言 gRPC 是一个高性能.开源和通用的 RPC 框架,面向移动和 HTTP/2 设计,带来诸如双向流.流控.头部压缩.单 TCP 连接上的多复用请求等特.这些特性使得其在移动设备上表现更好,更省电 ...

  8. gRPC-微服务间通信实践

    微服务间通信常见的两种方式 由于微服务架构慢慢被更多人使用后,迎面而来的问题是如何做好微服务间通信的方案.我们先分析下目前最常用的两种服务间通信方案. gRPC(rpc远程调用) 场景:A服务主动发起 ...

  9. grpc系列- protobuf详解

    Protocol Buffers 是一种与语言.平台无关,可扩展的序列化结构化数据的方法,常用于通信协议,数据存储等等.相较于 JSON.XML,它更小.更快.更简单,因此也更受开发人员的青眯. 基本 ...

随机推荐

  1. 【2020CSP-S模拟赛day5】总结

    爆零自闭赛 写在前面 于2022.11.1 这一次题目质量很高(以至于什么都不会) 再一度体验了省选Orz.比赛大体情况,刨去std, wzc神仙230分,比剩下的加起来都高.zyz神仙60分. 其余 ...

  2. jmeter报Address already in use: connect

    jmeter报Address already in use: connect   用windows进行jmeter压测出现java.net.BindException: Address already ...

  3. 容器调度 • Docker网络 • 持续交付 • 动态运行应用程序 部署的多元化

    <英雄联盟>在线服务运维之道 - InfoQ https://www.infoq.cn/article/running-online-services-riot/ 第一章 简 介 我是Jo ...

  4. gRPC设计动机和原则

    https://mp.weixin.qq.com/s/NMIIa0W722zo_AxCqASc0g TiDB 与 gRPC 的那点事儿 黄东旭 PingCAP 2017-08-10   gRPC 背景 ...

  5. How Load Balancing Policies Work

    How Load Balancing Policies Work https://docs.cloud.oracle.com/en-us/iaas/Content/Balance/Reference/ ...

  6. 【Coursera】Internet History 读书笔记

    前言 这个Internet History 有些令人劝退.电脑无法播放视频.手机不能播放.最后百度了改了hosts文件才可以. 附上解决方法: 解决coursera可以登录但无法播放视频 第一周 第三 ...

  7. Python学习【第5篇】:数据类型和变量总结

    字符串,数字,列表,元组,字典 可变不可变 1.可变:列表 如: p.p1 { margin: 0; font: 11px Menlo; color: rgba(0, 0, 0, 1); backgr ...

  8. MySQL安装+初始化操作(1)

    先去官网下载自己适合的版本,在这里我选择下载Windows 64位版本的,这是下载地址. 1.下载MySQL,步骤①==>步骤② 2.下载后,解压到除系统盘(C盘)之外的其他盘中 3.解压后在b ...

  9. 一:整合shiro

    整合shiro 1.原生的整个 1.1 创建项目 1.2 创建Realm 1.3 配置shiro 2.使用Shiro Starter 2.1 项目创建 2.2 创建Realm 2.3 配置Shiro ...

  10. Stream API处理集合

    使用流来遍历集合 简介 如何工作 总结 从集合或数组创建流 简介 如何工作 结论 聚合流的值 简介 如何工作 结论 转载 使用流来遍历集合 简介: Java的集合框架,如List和Map接口及Arra ...