【RPC】—Protobuf入门

news/2024/11/16 6:27:52/

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 TypeC++ TypeJava/Kotlin Type[1]Python Type[3]Go TypeRuby TypeC# TypePHP TypeDart Type
doubledoubledoublefloatfloat64Floatdoublefloatdouble
floatfloatfloatfloatfloat32Floatfloatfloatdouble
int32int32intintint32Fixnum or Bignum (as required)intintegerint
int64int64longint/longint64Bignumlonginteger/stringInt64
uint32uint32intint/longuint32Fixnum or Bignum (as required)uintintegerint
uint64uint64longint/longuint64Bignumulonginteger/stringInt64
sint32int32intintint32Fixnum or Bignum (as required)intintegerint
sint64int64longint/longint64Bignumlonginteger/stringInt64
fixed32uint32intint/longuint32Fixnum or Bignum (as required)uintintegerint
fixed64uint64longint/longuint64Bignumulonginteger/stringInt64
sfixed32int32intintint32Fixnum or Bignum (as required)intintegerint
sfixed64int64longint/longint64Bignumlonginteger/stringInt64
boolboolbooleanboolboolTrueClass/FalseClassboolbooleanbool
stringstringStringstr/unicodestringString (UTF-8)stringstringString
bytesstringByteStringstr (Python 2) bytes (Python 3)[]byteString (ASCII-8BIT)ByteStringstringList

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包含多个CustomerCustomer包含一个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在一定程度上可以保护数据,提升核心数据被破解的门槛,降低核心数据被盗爬的风险(也算是缺点变优点的典型范例)。


http://www.ppmy.cn/news/724911.html

相关文章

二叉树刷题总结

题单: 一,相同的树 题目: 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 题目接口: /*** Defin…

Linux——进程信号(上)

目录 前文 一,什么是进程信号 二,信号的产生 2.1 通过按键终端产生信号 2.2 调用系统函数向进程发信号 2.3 由软条件产生信号 2.4 硬件异常产生信号 总结 前文 上文主要讲了一下进程间用管道通信的相关知识,本文主要带领大家深度认识一…

手机号码归属地及运营商查询

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;public class NewMobile {public stati…

mysql手机号码规律查询

tips:所有手机号均为随机创建的,为了做查询的效果展示,不涉及他人隐私。 mysql手机号码规律查询 tips:所有手机号均为随机创建的,为了做查询的效果展示,不涉及他人隐私。数据库全号规律AAAABABAABBCCABCD(顺…

批量查询手机号码运营商信息

项目场景: 批量查询手机号码信息 问题描述: 有同事需要批量查询手机号码的运营商,归属地区号信息 思路: 百度搜索,爬虫取数,学的不精暂时还不会直接放弃python 自带一个phone库,缺点是查不到…

知识点速记 | 本机号码一键登录?

目录 中国移动 中国电信 很多 APP 的目前都支持「本机号码一键登录」功能。本机号码一键登录是基于运营商独有网关认证能力推出的账号认证产品。用户只需一键授权,即可实现以本机号码注册/登录,相比先前的短信验证码流程体验更优。 目前市面上有很多厂…

手机号码归属地查询 - 一刀工具

手机号码归属地快速查询移动,联通,电信手机号码归属地,免费手机号码运营商查询,手机归属地查询大全。 代码片段 //获取手机信息static function getMobile($mobile){try {$phone new PhoneHelper();$res $phone->setPhone($m…

JSP网上手机商城系统 用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 网上手机商城系统是一套完善的web设计系统,对理解JSP java SERLVET mvc编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,eclipse开发,数据库为Mysql5.0&a…