百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

了解一下ProtoBuf(了解一下相亲对象的年龄)

myzbx 2025-07-24 20:21 37 浏览

序列化与反序列化

我们在进行网络通信调用的时候,总是需要将内存的数据块经过序列化,转换成为一种可以通过网络流进行传输的格式。而这种格式在经过了传输之后再经过序列化,能还原成我们预想中的数据结构。

那么我们对于这种用于中间网络传输的数据格式就有一定的要求。首先它可以准确地描述数据内容,在此基础上我们则希望它尽量的小。

最开始流行起来的是XML,可扩展标记语言。由于它可以用来标记数据、定义数据类型,所以用户可以自己定义数据自己的语言,从而让对不同的数据结构化成统一的格式称为了可能。

而另外一个我们熟知的则是JSON(JavaScript Object Notation, JS 对象简谱)。尽管JSON中缺少了XML中的标签属性等描述方式,但是足够简介和清晰的层次结构使得其成为了必XML更受欢迎的数据交换格式。

同一份数据显然JSON的数据量比XML所使用的空间更少。那么空间省略在哪里呢?一方面是json使用更简单的字符来定义数据间的关联关系;另一方面是JSON减少了对数据类型的描述。但是丢少的数据类型再哪里呢?

以Java中的 OpenFeign 举例,JSON中缺少的类型定义被定义道程序中的接口中了。当进行序列化与反序列化时,JSON格式并不记录数据的类型,具体的数据类型在序列化方与反序列化方通过事先约定的接口来进行定义。这样就减少了信息传输过程中的信息量,从而让数据得以压缩。

但是JSON由于没有定义数据类型,所以在传输的过程中实际上就都是文本流,那么这种方法还可以进一步压缩吗?

ProtoBuf的原理概要

结合上文的讨论,我们先说结论:方法是有的,并写当前的实现方式是ProtoBuf。但在此之前我们先来了解一下ProtoBuf。

我们可以先看看官方给出的定义与描述:

protocol buffers 是一种与语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。 Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。 你可以定义数据的结构,然后使用特殊生成的源代码轻松地在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。

同样的,ProtoBuf也是一种支持序列化反序列化的方法,并且他具有很多优点:

  • 多语言
  • 多平台
  • 体积小
  • 扩展性好

实际上,ProtoBuf提供了一种通用的数据描述方式,这种定义数据的方式是通用的,就如同JSON或者XML一样。

接下来我们来来回答本节一开始的问题,针对JSON来说,ProtoBuf是如何将体积变得更小的呢?答案很简单,就是为数据序列化反序列化提供更多的先验知识。

本文暂不过度深入ProtoBuf原理,但是可以通过一张图来进行简要说明(图片来自网络):

ProtoBuf中的数据是按顺序进行排列,而整体的结构为若干个field,每一个field中由Tag-[Length]-Value组成。Length是可选的,而是否存在Length是通过Tag的类型来决定的。也就是说如果是指定的类型,比如int64,那我们就可以知道Value的长度,也就不用在依靠Length来对其空间进行描述(redis中的压缩列表也是这个思想)。

那么field应该对应的是什么字段呢?这个则是在序列化与反序列化时在ProtoBuf的服务端与客户端之间进行预先定义的。而因为提前定义了field的类型、排序,所以field本身可以不用对字段名、字段位置进行描述,只需要根据字段类型选用合适的二进制序列化方法,将字段本身的value值进行序列化传输即可。

稍微总结一下:

ProtoBuf通过对传输字段的名称、顺序进行预定义,从而在传输结构中只需要顺序的记录每个字段的类型标签和二进制值。

二进制序列化

尽管上文和官方中都是以XML或者JSON来对ProtoBuf进行对比。但是因为ProtoBuf本身就是二进制序列化方式,所以从压缩比上比较感觉有点欺负人。

对应的在Java中二进制常用的序列化器有Kryo和Hessian。但事实上,由于Kryo和Hessian中都需要对Java类名和字段信息进行存储。而ProtoBuf则只有Tag-Length-Value的数据对,且Value更是有针对性的特殊编码,所以空间占用小的很多。

Kryo是专门针对Java进行优化了的。所以在使用的便捷性上来说Kryo则更加方便。但ProtoBuf是跨平台的,且由于进行了字段的顺序定义,所以似的ProtoBuf定义后的接口是可以向前兼容的(只向后追加字段),而这种优势是Kryo所没有的。

使用ProtoBuf

ProtoBuf是跨语言的,使用ProtoBuf的第一步是先定一个proto 文件,而由于ProtoBuf 2和3语言版本的不同,其定义格式会有所不同,具体的细节还是得参考官方文档:
https://developers.google.cn/protocol-buffers/docs/proto3

对于ProtoBuf 3 的定义文档我们可以按如下方法定义:


syntax = "proto3";//指定版本为proto3,默认为proto2
message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    repeated int32 result = 3;
}

其中message关键字是定义的文件名,而 string、int32则是预定的字段类型,repeated则是描述字段为可重复任意多次的字段。

ProtoBuf通过这种形式的文件定义了传输信息的文件结构。

但是之前小节中我们知道了ProtoBuf是通过Tag-[Length]-Value组成的数据组来进行信息传输的,那么proto文件中定义的内容如何转换为实际传输的对象呢?

ProtoBuf的做法是,为每一种语言提供一个生成器protoc。通过使用protoc则可以根据.proto文件生成为一组java文件。对应的官方语法演示样例为:

protoc --proto_path=src --java_out=build/gen src/foo.proto

官方的生成参考为:
https://developers.google.com/protocol-buffers/docs/reference/java-generated

生成后的java文件将提供对应的实体以及数据的构造方法等文件,从而支持后续的使用。

需要注意的是,ProtoBuf是本质上是序列化方法,具体是通过Spring Cloud 的OpenFeign进行接口调用,还是通过grpc进行接口调用,都是可以的。

最后

本文对ProtoBuff进行了概念的整理,并没有对每个细节都进行深入的梳理,可以当作概念科普来进行阅读。



相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...