Proto3序列化协议

2024-09-03 13:58
文章标签 协议 序列化 proto3

本文主要是介绍Proto3序列化协议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Proto3序列化协议

简介

对于互联网应用来说,客户端-客户端、客户端-服务端之间需要数据的交互,其数据传输是二进制流的方式在互联网上传输,因为需要一种手段将数据对象编码为一种可以在网络上传输的二进制流,这个过程就叫做序列化。同样的,客户端在收到二进制流需要解码出数据,这个过程叫反序列。

简单理解就是序列化就是按照某种编码方式将数据转换为二进制流以方便在网络上传输,同时这种编码方式是可逆的和可理解的。

按照上述定义不难理解,json也是一种序列化的一种方式,将对象编码为字符串(二进制)进行传输。

同样的proto3是google推出的一种序列化框架。全称是Protocol Buffers。

其具有以下特点:

  • 小:生成的字节流采用了各种压缩方式,相对xml和json这类文件更小。

  • 快:编解码基本都是位运算,也没有复杂的嵌套关系,速度快。

  • 安全:这里的安全,是指protobuf没有把字段名写入到字节流里,只是写入了字段号信息。另外,相对于xml和json来说,因为被编码成二进制,破解成本增大。

编码方式

我们定义了一个Person的消息类型,那protobuf是怎么把它编码成二进制的呢?其实它是把message转成一系列的key-value,key就是字段号,value就是字段值,大概这样子存:

message Person {string name = 1;int32  id   = 2;
}

=1,=2称为tag, 唯一标识每个元素,其值不可重复,其中tag在1-15之间编码为一个字节,大于15字节将需要多个字节进行编码,因此作为优化手段,1-15 tag多用户经常出现的元素,15+的tag用于不长出现或者可选的元素,此外,对于repeated类型的message,其每个元素都需要一个tag,所以repeated适合用小于15的tag。

对于上述的定义,其会按照[tag1][value1][tag2][value2][tag3][value3]...的方式进行编码,

解码时,会从左往右解析每一个key-value,假如遇到某个key-value无法解析了,那么就直接跳过,不会影响到其它key-value的解析,因此如果你加了新字段,生成字节流,然后用旧版本解析,这时它还是能够解析出旧版本的字段的,新字段只是被忽略而已,这就是protobuf的向后兼容。

需要注意,一旦发布proto协议,其tag值就不能修改,新增字段只能使用未使用的tag(即使删除的tag也不可以),删除一个字段可以,解码时如果没有该字段会默认填充默认值,如果删除删除一个字段,最好采用reversed标识使用过的tag值,避免后续误使用旧的tag值。

官方建议:

  • xxx.proto一行最多80字符

  • 2个空格缩进

  • 字符串用双引号

  • 文件名小写、_组成,如lower_snake_case.proto

  • message 定义要驼峰式且首字母大写

message SongServiceRequest {required string song_name = 1;
}
  • 如果成员变量包含数组,应采用 song_name1 而不是 song_name_1

  • 对于repeated类型应该用复数,如repeated string keys = 1;

//类型是大写+驼峰式
enum FooBar {FOO_BAR_UNSPECIFIED = 0;  // 0值定义UNSPECIFIEDFOO_BAR_FIRST_VALUE = 1;  //值是全大写常量定义FOO_BAR_SECOND_VALUE = 2;
}
  • 对于Services定义
  //驼峰+大写service FooService {rpc GetSomething(FooRequest) returns (FooResponse); //函数名以驼峰+首字母大写}

这篇关于Proto3序列化协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133154

相关文章

如何在Spring Boot项目中集成MQTT协议

《如何在SpringBoot项目中集成MQTT协议》本文介绍在SpringBoot中集成MQTT的步骤,包括安装Broker、添加EclipsePaho依赖、配置连接参数、实现消息发布订阅、测试接口... 目录1. 准备工作2. 引入依赖3. 配置MQTT连接4. 创建MQTT配置类5. 实现消息发布与订阅

使用Python进行GRPC和Dubbo协议的高级测试

《使用Python进行GRPC和Dubbo协议的高级测试》GRPC(GoogleRemoteProcedureCall)是一种高性能、开源的远程过程调用(RPC)框架,Dubbo是一种高性能的分布式服... 目录01 GRPC测试安装gRPC编写.proto文件实现服务02 Dubbo测试1. 安装Dubb

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht

SpringBoot项目中Redis存储Session对象序列化处理

《SpringBoot项目中Redis存储Session对象序列化处理》在SpringBoot项目中使用Redis存储Session时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在Spri... 目录一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

如何配置Spring Boot中的Jackson序列化

《如何配置SpringBoot中的Jackson序列化》在开发基于SpringBoot的应用程序时,Jackson是默认的JSON序列化和反序列化工具,本文将详细介绍如何在SpringBoot中配置... 目录配置Spring Boot中的Jackson序列化1. 为什么需要自定义Jackson配置?2.

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优