proto3 协议指引
一、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 协议指引的更多相关文章
- Golang使用proto3协议导致零值字段不显示
Golang使用proto3协议导致零值字段不显示 问题描述 proto协议生成的结构体如果使用直接转成json会导致零值字段不显示,这样的json是有毛病的,可以使用如下方法解决 示例Demo pa ...
- Golang语言下使用Protocol Buffer教程
代码仓库地址 一.介绍 Protobuf是Google旗下的一款平台无关,语言无关,可扩展的序列化结构数据格式.所以很适合用做数据存储和作为不同应用,不同语言之间相互通信的数据交换格式,只要实现相同的 ...
- .NET Core使用gRPC打造服务间通信基础设施
一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制. 利用这种传输机制,不同进程(或服务)间像调用本地进程中 ...
- HTTP和RPC是现代微服务架构,HTTP和RPC是现代微服务架构
.NET Core使用gRPC打造服务间通信基础设施 一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制 ...
- 使用gRPC打造服务间通信基础设施
一.什么是RPC rpc(远程过程调用)是一个古老而新颖的名词,他几乎与http协议同时或更早诞生,也是互联网数据传输过程中非常重要的传输机制. 利用这种传输机制,不同进程(或服务)间像调用本地进程中 ...
- protobuf3的学习笔记
学习protobuf的过程中踩了不少的坑,这篇博文算是一个小结吧! 环境: windows VisualStudio Google.Protobuf.Tools. Google.Protobuf. 其 ...
- GO gRPC教程-环境安装(一)
前言 gRPC 是一个高性能.开源和通用的 RPC 框架,面向移动和 HTTP/2 设计,带来诸如双向流.流控.头部压缩.单 TCP 连接上的多复用请求等特.这些特性使得其在移动设备上表现更好,更省电 ...
- gRPC-微服务间通信实践
微服务间通信常见的两种方式 由于微服务架构慢慢被更多人使用后,迎面而来的问题是如何做好微服务间通信的方案.我们先分析下目前最常用的两种服务间通信方案. gRPC(rpc远程调用) 场景:A服务主动发起 ...
- grpc系列- protobuf详解
Protocol Buffers 是一种与语言.平台无关,可扩展的序列化结构化数据的方法,常用于通信协议,数据存储等等.相较于 JSON.XML,它更小.更快.更简单,因此也更受开发人员的青眯. 基本 ...
随机推荐
- canvas星空背景特效+CSS旋转相册学习
今天在看帖子的时候,看到了个有趣的css旋转相册,刚好之前做了一个星空背景dome,这里给大家分享下代码: 旋转相册参考:https://blog.csdn.net/gitchatxiaomi/art ...
- 【网络安全】IOC概念浅析
OpenIOC(Open Indicator of Compromise,开放威胁指标) MANDIANT 公司发布的情报共享规范,是开源.灵活的框架.OpenIOC是一个记录.定义以及共享威胁情报的 ...
- 游戏中的AOI(Area of Interest)算法
游戏中的AOI(Area of Interest)算法 游戏的AOI算法应该算作游戏的基础核心了,许多逻辑都是因为AOI进出事件驱动的,许多网络同步数据也是因为AOI进出事件产生的.因此,良好的AOI ...
- okhttp踩坑
ResponseBody.string() 平常我们用的客户端http调用工具一般是RestTemplate,HttpClient,okhttp,以前使用过前两者,没咋接触过okhttp,我看公司 ...
- js部分知识整理,google浏览器的代码调试
整理一些学过的js知识点,包括js中3个括号的含义,this的使用,递归,google浏览器的代码调试.Location的属性及常用方法,window对象常用方法,open方法等. js括号 在js中 ...
- 使用session实现网站N天免登陆()
问题描述: 一些网站的N天之内免登陆实现方式. 方式一: 首先想到的是使用cookie保存用户登录信息,设置有效期,在用户下次访问时免去登录环节,直接通过cookie获取用户信息. 方式二: 方式二: ...
- 项目Js源码整合
整合一下目前做的项目中JS中用到的相关源码等,留待记录和使用. 一.ajaxgrid源码部分 1.初始化 2.查询 3.删除 4.保存 5.根据id获取值,时间值等 6.详情.跳转链接 : a 标签 ...
- OpenStack (horizon Web管理界面)
horizon 简介 Horizon 为 Openstack 提供一个 WEB 前端的管理界面 (UI 服务 )通过 Horizone 所提供的 DashBoard 服务 , 管理员可以使用通过 WE ...
- Python 字符串指定位置替换字符
指定位置替换字符 def replace_char(old_string, char, index): ''' 字符串按索引位置替换字符 ''' old_string = str(old_string ...
- sentinel流量控制和熔断降级执行流程之源码分析
前言: sentinel是阿里针对服务流量控制.熔断降级的框架,如何使用官方都有很详细的文档,下载它的源码包 里面对各大主流框都做了适配按理,本系列文章目的 主要通过源码分析sentinel流量控制和 ...