【RPC】—Protobuf入门
Protobuf入门
⭐⭐⭐⭐⭐⭐
Github主页👉https://github.com/A-BigTree
笔记链接👉https://github.com/A-BigTree/Code_Learning
⭐⭐⭐⭐⭐⭐
Spring专栏👉https://blog.csdn.net/weixin_53580595/category_12279588.html
SpringMVC专栏👉https://blog.csdn.net/weixin_53580595/category_12281721.html
Mybatis专栏👉https://blog.csdn.net/weixin_53580595/category_12279566.html
如果可以,麻烦各位看官顺手点个star~😊
如果文章对你有所帮助,可以点赞👍收藏⭐支持一下博主~😆
文章目录
- Protobuf入门
- 1 前言
- 2 什么是Protocol Buffer
- 2.1 技术背景
- 2.2 Protobuf在谷歌业务中的地位
- 3 Protocol协议的消息定义
- 4 Protobuf的代码生成
- 5 Protobuf的优点
- 5.1 效率高
- 5.2 支持跨平台、多语言
- 5.3 扩展性、兼容性好
- 5.4 使用简单
- 6 Protobuf的缺点
1 前言
在IM应用中,优化数据流量消耗过多的基本方法就是使用高度压缩的通讯协议,而数据压缩后流量减小带来的自然结果也就是省电:因为大数据量的传输必然需要更久的网络操作、数据序列化及反序列化操作,这些都是电量消耗过快的根源。
当前IM应用中最热门的通讯协议无疑就是Google的Protobuf了,基于它的优秀表现,微信和手机QQ这样的主流IM应用也早已在使用它。
2 什么是Protocol Buffer
什么是 Google Protocol Buffer?
Google Protocol Buffer(简称 Protobuf)是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 个 .proto 文件。他们常用于 RPC 系统和持续数据存储系统等应用场景。
实际上: Protocol Buffers(简称 Protobuf)是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
目前: Protobuf官方工程主页上显示的已支持的开发语言多达10种,分别有:C++、Java、Python、Objective-C、C#、Ruby、Go、PHP、Dart、Javascript,基本上主流的语言都已支持(具体详见Protobuf工程主页:https://github.com/protocolbuffers/protobuf)。
Protobuf数据类型与其他语言的对照:
| .proto Type | C++ Type | Java/Kotlin Type[1] | Python Type[3] | Go Type | Ruby Type | C# Type | PHP Type | Dart Type |
|---|---|---|---|---|---|---|---|---|
| double | double | double | float | float64 | Float | double | float | double |
| float | float | float | float | float32 | Float | float | float | double |
| int32 | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | int |
| int64 | int64 | long | int/long | int64 | Bignum | long | integer/string | Int64 |
| uint32 | uint32 | int | int/long | uint32 | Fixnum or Bignum (as required) | uint | integer | int |
| uint64 | uint64 | long | int/long | uint64 | Bignum | ulong | integer/string | Int64 |
| sint32 | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | int |
| sint64 | int64 | long | int/long | int64 | Bignum | long | integer/string | Int64 |
| fixed32 | uint32 | int | int/long | uint32 | Fixnum or Bignum (as required) | uint | integer | int |
| fixed64 | uint64 | long | int/long | uint64 | Bignum | ulong | integer/string | Int64 |
| sfixed32 | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | int |
| sfixed64 | int64 | long | int/long | int64 | Bignum | long | integer/string | Int64 |
| bool | bool | boolean | bool | bool | TrueClass/FalseClass | bool | boolean | bool |
| string | string | String | str/unicode | string | String (UTF-8) | string | string | String |
| bytes | string | ByteString | str (Python 2) bytes (Python 3) | []byte | String (ASCII-8BIT) | ByteString | string | List |
2.1 技术背景
Protobuf最先开始是 Google用来解决索引服务器 request/response 协议的。在没有Protobuf之前,Google 已经存在了一种 request/response 格式,用于手动处理 request/response 的编解码。
如果是非常明确的格式化协议,会使新协议变得非常复杂。因为开发人员必须确保请求发起者与处理请求的实际服务器之间的所有服务器都能理解新协议,然后才能切换开关以开始使用新协议。这也就是每个服务器开发人员都遇到过的低版本兼容、新旧协议兼容相关的问题。为了解决这些问题,于是Protobuf就诞生了。
2.2 Protobuf在谷歌业务中的地位
Protobuf 现在是 Google 用于数据交换和存储的通用语言。谷歌代码树中定义了 48162 种不同的消息类型,包括12183个 .proto 文件。它们既用于 RPC 系统,也用于在各种存储系统中持久存储数据。
Protobuf 诞生之初是为了解决服务器端新旧协议(高低版本)兼容性问题,名字也很体贴——“协议缓冲区”,只不过后期慢慢发展成用于传输数据。
3 Protocol协议的消息定义
Protobuf 的消息是在idl文件(.proto)中描述的。
syntax = "proto3";package domain;option java_package = "com.Protobuf.generated.domain";
option java_outer_classname = "CustomerProtos";message Customers {repeated Customer customer = 1;
}message Customer {int32 id = 1;string firstName = 2;string lastName = 3;enum EmailType {PRIVATE = 0;PROFESSIONAL = 1;}message EmailAddress {string email = 1;EmailType type = 2;}repeated EmailAddress email = 5;
}
上面的消息比较简单,Customers包含多个Customer(Customer包含一个id字段、一个firstName字段、一个lastName字段以及一个email的集合)。
除了上述定义外,文件顶部还有三行可帮助代码生成器的声明:
syntax = "proto3":用于idl语法版本,目前有两个版本proto2和proto3,两个版本语法不兼容,如果不指定,默认语法是proto2(由于proto3比proto2支持的语言更多,语法更简洁,本文使用的是proto3);package domain:此配置用于嵌套生成的类/对象;option java_package:生成器还使用此配置来嵌套生成的源(此处的区别在于这仅适用于Java,在使用Java创建代码和使用JavaScript创建代码时,使用了两种配置来使生成器的行为有所不同。也就是说,Java类是在包com.Protobuf.generated.domain下创建的,而JavaScript对象是在包domain下创建的);
4 Protobuf的代码生成
首先安装 Protobuf 编译器 protoc(点这里有详细的安装教程)。
安装完成后,可以使用以下命令生成 Java 源代码:
protoc --java_out=./src/main/java ./src/main/idl/customer.proto
**上述命令的意图是:**从项目的根路径执行该命令,并添加了两个参数 java_out(即定义 ./src/main/java/ 为Java代码的输出目录;而 ./src/main/idl/customer.proto 是.proto文件所在目录)。
生成的代码很复杂,但用法却很简单:
CustomerProtos.Customer.EmailAddress email = CustomerProtos.Customer.EmailAddress.newBuilder().setType(CustomerProtos.Customer.EmailType.PROFESSIONAL).setEmail("crichardson@email.com").build();CustomerProtos.Customer customer = CustomerProtos.Customer.newBuilder().setId(1).setFirstName("Lee").setLastName("Richardson").addEmail(email).build();
// 序列化
byte[] binaryInfo = customer.toByteArray();
System.out.println(bytes_String16(binaryInfo));
System.out.println(customer.toByteArray().length);
// 反序列化
CustomerProtos.Customer anotherCustomer = CustomerProtos.Customer.parseFrom(binaryInfo);
System.out.println(anotherCustomer.toString());
5 Protobuf的优点
5.1 效率高
从序列化后的数据体积角度,与XML、JSON这类文本协议相比,Protobuf通过 T-(L)-V(TAG-LENGTH-VALUE)方式编码,不需要", {, }, :等分隔符来结构化信息。同时在编码层面使用varint压缩。
所以描述同样的信息,Protobuf序列化后的体积要小很多,在网络中传输消耗的网络流量更少,进而对于网络资源紧张、性能要求非常高的场景。比如在移动网络下的IM即时通讯应用中,Protobuf协议就是非常不错的选择。
从序列化/反序列化速度角度,与XML、JSON相比,Protobuf序列化/反序列化的速度更快,比XML要快20-100倍。
5.2 支持跨平台、多语言
Protobuf是平台无关的,无论是Android、iOS、PC,还是C#与Java,都可以利用Protobuf进行无障碍通讯。
5.3 扩展性、兼容性好
Protobuf具有向后兼容的特性:更新数据结构以后,老版本依旧可以兼容,这也是Protobuf诞生之初被寄予解决的问题,因为编译器对不识别的新增字段会跳过不处理。
5.4 使用简单
Protobuf 提供了一套编译工具,可以自动生成序列化、反序列化的样板代码,这样开发者只要关注业务数据idl,简化了编码解码工作以及多语言交互的复杂度。
6 Protobuf的缺点
- 不具备自描述能力:跟XML、JSON相比,这两者是自描述的,而
ProtoBuf则不是; - 数据可读性非常差:
ProtoBuf是二进制协议,如果没有idl文件,就无法理解二进制数据流,对调试非常不友好;
由于没有idl文件无法解析二进制数据流,ProtoBuf在一定程度上可以保护数据,提升核心数据被破解的门槛,降低核心数据被盗爬的风险(也算是缺点变优点的典型范例)。
相关文章:
【RPC】—Protobuf入门
Protobuf入门 ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ Spring专栏👉https://blog.csdn.net/weixin_53580595/category_12279588.html SpringMVC专栏&a…...
【⑩MySQL】:表管理,让数据管理不再困难
前言 ✨欢迎来到小K的MySQL专栏,本节将为大家带来MySQL表/数据库创建和管理的讲解✨ 目录 前言1. 基础知识2. 创建和管理数据库3.创建表4. 修改表5. 删除表6.总结 1. 基础知识 ✨1.1 表的基本概念 在MySQL数据库中,表是一种很重要的数据库对象…...
Springboot项目使用原生Websocket
目录 1.启用Websocket功能2.封装操作websocket session的工具3.保存websocket session的接口4.保存websocket session的类5.定义websocket 端点6.创建定时任务 ping websocket 客户端 1.启用Websocket功能 package com.xxx.robot.config;import org.springframework.context.a…...
在Vue 3中如何实现服务端渲染(SSR)
今天我要给你们介绍一个很酷的功能——在Vue 3中实现服务端渲染(SSR) 首先,我们来聊聊SSR是什么。它就像是一个魔术师,能让你的网页在服务器上就预先渲染好,然后发送到客户端。想象一下,你在浏览一个网页&…...
【计算机组成原理期末课设作业】16位微型计算机实现——MOVS串传送扩展指令设计
16位微型计算机实现——MOVS串传送扩展指令设计😎 前言🙌教学目的:1、数据**加粗样式**通路分析2、微程序控制器分析3、指令系统分析4、微程序控制器指令周期流程图5、微指令编码6、测试程序和运行结果(1)首先先在内存…...
CodeMirror 对 XML 文档熟悉及元素控制自定义
CodeMirror 是一个网络代码编辑器组件。它可以在网站中用于实现支持多种编辑功能的文本输入字段,并具有丰富的编程接口以允许进一步扩展。 本文为 xml 格式的代码提示约束格式规范的自定义示例内容。 先看效果,如下: 官方 Demo 的完整代码如…...
Jetpack - ViewModel
一、概念 二、使用 2.1 创建ViewModel //无参 class MainViewModel : ViewModel() {} //有参 class MainViewModel(mainRepository: MainRepository) : ViewModel() {} class MainViewModelFactory(private val mainRepository: MainRepository) : ViewModelProvider.Factor…...
【新版系统架构】第十三章-层次式架构设计理论与实践
软考-系统架构设计师知识点提炼-系统架构设计师教程(第2版) 第一章-绪论第二章-计算机系统基础知识(一)第二章-计算机系统基础知识(二)第三章-信息系统基础知识第四章-信息安全技术基础知识第五章-软件工程…...
剖析Linux文件系统
Linux 文件系统体系结构是一个对复杂系统进行抽象化的有趣例子。通过使用一组通用的 API 函数,Linux 可以在许多种存储设备上支持许多种文件系统。例如,read 函数调用可以从指定的文件描述符读取一定数量的字节。read 函数不了解文件系统的类型ÿ…...
简介Maven结构与配置方法
一、Maven是什么 Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。 它有什么用呢? 比如我以前要IOUtils这个包,那要到网站下去下载下来,再导入。 当jar包多的时候,一个一个导出,…...
好用的网址6
PPT课件网:http://www.pptkj.net/ ImgUpscaler:AI Image Upscaler - Upscale Photo, Cartoons in Batch Free 加强图片 AI Draw:AI Draw | Convert Images to One-Line Drawings with AI ZToDoList:https://www.ztodolis…...
MySQL数据库---笔记5
MySQL数据库---笔记5 一、锁1.1、介绍1.2、全局锁1.2.1、全局锁介绍1.2.2、一致性数据备份 1.3、表级锁1.3.1、表锁1.3.2、元数据锁(meta data lock , MDL)1.3.3、意向锁 1.4、行级锁1.4.1、介绍1.4.2、行锁1.4.3、间隙锁/临建锁 二、InnoDB引擎2.1、逻辑…...
Yocto:初始
1.构建Yocto项目前,需要先安装其所依赖的一些组件及工具 1 System Requirements — The Yocto Project 4.2.999 documentation 需要依次安装: $ sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential chrpath socat cpio python3 python3-pip python…...
autodl算力租用平台应用于pycharm
一、GPU租用选择 1、创建实例 首先进入算力市场 博客以2080为例,选择计费方式,选择合适的主机,选择要创建实例中的GPU数量,选择镜像(内置了不同的深度学习框架),最后创建即可 2、SSH远程连…...
高德地图的使用
JS API 结合 Vue 使用 高德地图 jsapi 下载、引入 npm add amap/amap-jsapi-loaderimport AMapLoader from amap/amap-jsapi-loader 使用2.0版本的loader需要在window对象下先配置 securityJsCode JS API 安全密钥使用 JS API 使用 script 标签同步加载增加代理服务器设置…...
<List<Map<String,String>>> 删除元素常见的误区以及删除方法
看到这么标题可能觉得这个真是太easy了,不就remove吗,分分钟搞定。 但结果却出乎意料,下面我们来j简单说说list删除数据可能遇到的坑: 先说明我们可能会遇到的两个问题: 1.java.lang.IndexOutOfBoundsException(索引越…...
Linux下的编辑器——vim的简单上手指南
文章目录 一.概念1. 什么是 vim2. Vim 的模式①命令模式② 插入模式③底线命令模式 二.vim的基本操作1.如何启动vim?2. [命令模式」切换至 「插入模式」3.「插入模式」 切换至 「命令模式」4.「命令模式」切换至 「底行模式」5. 如何退出 vim? 三.vim指令…...
C++多线程学习(二、多线程的几种创造方式【有返回值的之后讲】)
目录 创建多线程 1.普通函数充当线程处理函数创造线程 2.Lambda表达式充当线程处理函数 3.带参函数创建线程 3.1普通参数 3.2传入引用 3.3智能指针充当函数参数 4.通过类中的成员函数创建 4.1仿函数方式创建:类名的方式调用 4.2普通类中的成员函数 创建多…...
前端开发框架生命周期详解:Vue、React和Angular
引言 作为前端开发者,掌握前端开发框架的生命周期是非常重要的。在现代Web应用开发中,Vue.js、React和Angular是三个最流行的前端开发框架。本篇博客将详细解读这三个框架的生命周期,包括每个阶段的含义、用途以及如何最大限度地利用它们。通…...
【Java从入门到大牛】程序流程控制
🔥 本文由 程序喵正在路上 原创,CSDN首发! 💖 系列专栏:Java从入门到大牛 🌠 首发时间:2023年7月7日 🦋 欢迎关注🖱点赞👍收藏🌟留言🐾…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
