一、protocal buffer 是什么?

一种序列化机制。

什么是序列化?

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

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

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

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

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

可扩展

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

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

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

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

proto3 文件:.proto

  1. syntax = "proto3";
  2.  
  3. message SearchRequest {
  4. string query = 1;
  5. int32 page_number = 2;
  6. int32 result_per_page = 3;
  7. }

第一行声明当前使用的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,使用如下:

  1. import "google/protobuf/wrappers.proto";

wappers.proto文件定义如下:

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  
  31. // Wrappers for primitive (non-message) types. These types are useful
  32. // for embedding primitives in the `google.protobuf.Any` type and for places
  33. // where we need to distinguish between the absence of a primitive
  34. // typed field and its default value.
  35. //
  36. // These wrappers have no meaningful use within repeated fields as they lack
  37. // the ability to detect presence on individual elements.
  38. // These wrappers have no meaningful use within a map or a oneof since
  39. // individual entries of a map or fields of a oneof can already detect presence.
  40.  
  41. syntax = "proto3";
  42.  
  43. package google.protobuf;
  44.  
  45. option csharp_namespace = "Google.Protobuf.WellKnownTypes";
  46. option cc_enable_arenas = true;
  47. option go_package = "github.com/golang/protobuf/ptypes/wrappers";
  48. option java_package = "com.google.protobuf";
  49. option java_outer_classname = "WrappersProto";
  50. option java_multiple_files = true;
  51. option objc_class_prefix = "GPB";
  52.  
  53. // Wrapper message for `double`.
  54. //
  55. // The JSON representation for `DoubleValue` is JSON number.
  56. message DoubleValue {
  57. // The double value.
  58. double value = 1;
  59. }
  60.  
  61. // Wrapper message for `float`.
  62. //
  63. // The JSON representation for `FloatValue` is JSON number.
  64. message FloatValue {
  65. // The float value.
  66. float value = 1;
  67. }
  68.  
  69. // Wrapper message for `int64`.
  70. //
  71. // The JSON representation for `Int64Value` is JSON string.
  72. message Int64Value {
  73. // The int64 value.
  74. int64 value = 1;
  75. }
  76.  
  77. // Wrapper message for `uint64`.
  78. //
  79. // The JSON representation for `UInt64Value` is JSON string.
  80. message UInt64Value {
  81. // The uint64 value.
  82. uint64 value = 1;
  83. }
  84.  
  85. // Wrapper message for `int32`.
  86. //
  87. // The JSON representation for `Int32Value` is JSON number.
  88. message Int32Value {
  89. // The int32 value.
  90. int32 value = 1;
  91. }
  92.  
  93. // Wrapper message for `uint32`.
  94. //
  95. // The JSON representation for `UInt32Value` is JSON number.
  96. message UInt32Value {
  97. // The uint32 value.
  98. uint32 value = 1;
  99. }
  100.  
  101. // Wrapper message for `bool`.
  102. //
  103. // The JSON representation for `BoolValue` is JSON `true` and `false`.
  104. message BoolValue {
  105. // The bool value.
  106. bool value = 1;
  107. }
  108.  
  109. // Wrapper message for `string`.
  110. //
  111. // The JSON representation for `StringValue` is JSON string.
  112. message StringValue {
  113. // The string value.
  114. string value = 1;
  115. }
  116.  
  117. // Wrapper message for `bytes`.
  118. //
  119. // The JSON representation for `BytesValue` is JSON string.
  120. message BytesValue {
  121. // The bytes value.
  122. bytes value = 1;
  123. }

五、枚举

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. Podinfo,迷你的 Go 微服务模板

    ​项目介绍 Podinfo 是一个用 Go 制作的小型 web 应用程序,它展示了在 Kubernetes 中运行微服务的最佳实践. 它已实现的技术指标(截选自官方 README.md ): 里面每一 ...

  2. linux登陆欢迎信息及命令提示符修改

    登录信息修改 登陆信息显示数据 : /etc/issue and /etc/motd 登陆终端机的时候,会有几行提示的字符串,这些设置在/etc/issue里面可以修改,提示内容在/etc/motd中 ...

  3. 支付宝沙箱环境使用(Alipay Easy SDK ) .Net示例

    新版服务端 SDK(Alipay Easy SDK)适用于 Java.C#.PHP 编程语言,对开放能力的 API 进行了更加贴近高频场景的精心设计与裁剪,简化了服务端调用方式,让开发者享受极简编程体 ...

  4. 【转载】HTTP 协议详细介绍

    背景 当你在浏览器地址栏敲入"http://www.cnblogs.com/",然后猛按回车,呈现在你面前的,将是博客园的首页了(这真是废话,你会认为这是理所当然的).作为一个开发 ...

  5. Python 2.x 和 Python 3.x

    Python 2.x 默认不支持中文,具体原因,等到介绍 字符编码 时给大家讲解 Python 2.x 的解释器名称是 python Python 3.x 的解释器名称是 python3 目前市场上有 ...

  6. js控制页面元素值

    // TODO id 定位 var ele1 = document.getElementById("test1"); // alert(ele1.value) // TODO 根据 ...

  7. P5687 网格图

    算法原理 根据 \(\operatorname{Kruskal}\) 算法的运算规则,每次总是会把当前边权最小,且连接着本不连通的两个点的边选中. 而在这道题目中,位于同一行或列的边的边权大小一定是相 ...

  8. centos安装Qt

    转:http://blog.csdn.net/wavelee/article/details/7855727 在编译Qt4.8.6版本的库时,在配置时 ./configure 出现了如下的错误: Ba ...

  9. linux系统命令(调试命令)(nmtui,ip a、ss、ps、uptime、top、lsof、grep,iotop、iftop)

    本章命令 0 1 2 3 4 5 6 7 8 9 10 nmtui ip a ss ps uptime top lsof grep iotop iftop tsar nmtui 图形化管理网卡命令 依 ...

  10. JDK-7新特性,更优雅的关闭流-java try-with-resource语句使用

    前言 公司最近代码质量整改,需要对大方法进行调整,降低到50行以下,对方法的深度进行降低,然后有些文件涉及到流操作,很多try/catch/finally语句,导致行数超出规范值,使用这个语法可以很好 ...