0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Google二进制编解码技术之Protobuf 1

jf_78858299 来源: 码农的荒岛求生 作者:陆小风 2023-02-15 14:28 次阅读

计算机网络编程中一个非常基本的问题:该怎样表示client与server之间交互的数据,在往下看之前先想一想这个问题。

共识与协议

这个问题可不像看上去的那样简单,因为client进程和server进程运行在不同的机器上,这些机器可能运行在不同的处理器平台、可能运行在不同的操作系统、可能是由不同的编程语言编写的,server要怎样才能识别出client发送的是什么数据呢?就像这样:图片client给server发送了一段数据:

0101000100100001

server怎么能知道该怎样“解读”这段数据呢?

显然,client和server在发送数据之前必须首先达成某种关于怎样解读数据的共识,这就是所谓的 协议

这里的协议可以是这样的:“将每8个比特为一个单位解释为无符号数字”,如果协议是这样的,那么server接收到这串二进制后就会将其解析为81(01010001)与33(00100001)。

当然,这里的协议也可以是这样的:“将每8个比特为一个单位解释为ASCII字符”,那么server接收到这串二进制后就将其解析为“Q!”。

可见,同样一串二进制在不同的“上下文/协议”下有完全不一样的解读,这也是为什么计算机明明只认知0和1但是却能处理非常复杂任务的根本原因,因为一切都可以编码为0和1,同样的我们也可以从0和1中解析出我们想要的信息,这就是所谓的编解码技术。

实际上不止0和1,我们也可以将信息编码为摩斯密码(Morse code)等,只不过计算机擅长处理0和1而已。

扯远了,回到本文的主题。

远程过程调用:RPC

作为程序员我们知道,client以及server之间不会简单传递一串数字以及字符这样简单,尤其在互联网大厂后端服务这种场景下。

当我们在电商App搜索商品、打车App呼叫出租车以及刷短视频时,每一次请求的背后在后端都涉及大量服务之间的交互,就像这样:

图片

完成一次客户端请求gateway这个服务要调用N多个下游服务,所谓调用是说A服务向B服务发送一段数据(请求),B服务接收到这段数据后执行相应的函数,并将结果返回给A服务。

只不过对于服务A来说并不想关心网络传输这样的底层细节,如果能像调用本地函数一样调用远程服务就好了,这就是所谓的RPC,经典的实现方式是这样的:

图片

RPC对上层提供和普通函数一样的接口,只不过在实现上封装了底层复杂的网络通信,RPC框架是当前互联网后端的基石之一,很多所谓互联网后端的职位无非就是在此基础之上堆业务逻辑。

本文我们不关心其中的细节,这里我们只关心在网络层client是怎样对请求参数进行编码、server怎样对请求参数进行解码的,也就是本文开头提出的问题。

信息的编解码

在思考怎样进行编解码之前我们必须意识到:

  • client和server可能是用不同语言编写的,你的编解码方案必须通用且不能和语言绑定
  • 编解码方法的性能问题,尤其是对时间要求苛刻的服务

首先,我们最应该能想到的就是以纯文本的形式来表示。

纯文本从来都是一种非常有友好的信息载体,为什么?很简单,因为人类(我们)可以直接看懂,就像这段:

{
 "widget": {
  "window": {
   "title": "Sample Konfabulator Widget",
   "name": "main_window",
   "width": 500,
   "height": 500
  },
  "image": { 
   "src": "Images/Sun.png",
   "name": "sun1",
   "hOffset": 250,
   "vOffset": 250,
  },
 }
}

是不是很清晰,一目了然,只要我们实现约定好文本的结构(也就是语法),那么client和server就能利用这种文本进行信息的编码以及解码,不管client和server是运行在x86还是Arm、是32位的还是64位的、运行在Linux上还是windows上、是大端还是小端,都可以无障碍交流。

因此在这里,文本的语法就是一种协议。图片顺便说一句, 你都规定好了文本的语法,实际上就相当于发明了一种语言

这里用来举例用的语言就是所谓的Json,只不过json这种语言不是用来表示逻辑(代码)而是用来存储数据的。

Json就是这个老头提出来的:

除了Json,另一种利用文本存储数据的表示方法是XML,来一段感受下:

<note>
<to>Toveto>
<from>Janifrom>
<heading>Reminderheading>
<body>Don't forget me this weekend!body>
note>

相对Json来说是不是就没那么容易看懂了,Json出现后在web领域逐渐取代了XML。

当两段数据量很少的时候——就像浏览器和服务端的交互,Json可以工作的非常好,这个场景就是这里:图片在这里是json的天下。

但对于后端服务之间的交互来说就不一样了,后端服务之间的RPC调用可能会传输大量数据,如果全部用纯文本的形式来表示数据那么不管是网络带宽还是性能可能都会差强人意。图片

在这种场景下,Json并不是最好的选项,主要原因之一就在于性能以及数据的体积。

我们知道,文本表示对人类是最友好的,对机器来说则不是这样,对机器来说最好的还是01二进制。

那么有没有二进制的编码方法吗?答案是肯定的,这就是当前互联网后端中流行的protobuf,Google公司开源项目。

那么protobuf有什么神奇之处吗?

假设client端想给server端传输这样一段信息:“我有一个id,其值为43”,那么在XML下是这样表示的:

<id>43id>

数一数这这段数据占据了多少字节,很显然是11字节;

而如果用json来表示呢?

{"id":43}

数一数这段数据占据了多少字节,显然是9字节;

而如果用protobuf来表示呢? 是这样的:

// 消息定义
message Msg {
  optional int32 id = 1;
}

// 实例化
Msg msg;
msg.set_id(43);

其中Msg的定义看上去比Json和XML更加复杂了,但这些只是给人看的,这些还会被protbuf进一步处理,最终被编码为:

082b

也就是0x08与0x2b,这占据了多少字节呢?答案是2字节。

从json的9字节到protobuf的2字节,数据大小减少了4倍多,数据量的减少意味着:

  • 更少的网络带宽
  • 更快的解析速度

那么protobuf是怎样做到这一点的呢?

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 计算机
    +关注

    关注

    19

    文章

    7494

    浏览量

    87966
  • Server
    +关注

    关注

    0

    文章

    90

    浏览量

    24037
  • 网络编程
    +关注

    关注

    0

    文章

    71

    浏览量

    10075
收藏 人收藏

    评论

    相关推荐

    探讨2对4二进制解码器及4到16二进制解码器配置

    二进制解码器是由单独的逻辑门构成的另一种组合逻辑电路,与编码器完全相反。名称“解码器”是指将编码信息从一种格式转换或解码为另一种格式,因此二进制
    的头像 发表于 12-29 12:10 1.1w次阅读
    探讨2对4<b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器及4到16<b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器配置

    二进制相对调相(二进制差分调相2DPSK)的工作原理

    二进制相对调相(二进制差分调相2DPSK)的工作原理
    发表于 10-21 13:01 3205次阅读
    <b class='flag-5'>二进制</b>相对调相(<b class='flag-5'>二进制</b>差分调相2DPSK)的工作原理

    二进制

    二进制   二进制与十进制的区别在于数码的个数和进位规律有很大的区别,顾名思义,二进制的计数规律为逢二进一,是以2为基数的计数体制。10这
    发表于 04-06 23:48 8200次阅读
    <b class='flag-5'>二进制</b>

    二进制时钟电路

    二进制时钟电路
    发表于 09-11 11:22 3114次阅读
    <b class='flag-5'>二进制</b>时钟电路

    同步二进制计数器

    同步二进制计数器 1.   同步与异步二进制加法计数器比较态序表和工作波形一样电路结构不同:  异步二进制加法
    发表于 09-30 18:37 1.2w次阅读
    同步<b class='flag-5'>二进制</b>计数器

    二进制编码和二进制数据

    二进制编码和二进制数据   二进制编码是计算机内使用最多的码制,它只使用两个基本符号"0"和"1",并且通过由这两个符号组成的
    发表于 10-13 16:22 4790次阅读

    二进制数的运算规则

    二进制数的运算规则  二进制数之间可以执行算术运算和逻辑运算,其规则简单,容易实现。  (1) 加法运算规则    0 + 0 = 0         例如:
    发表于 10-13 16:24 2.3w次阅读

    什么是二进制计数器,二进制计数器原理是什么?

    什么是二进制计数器,二进制计数器原理是什么? 计数器是数字系统中用得较多的基本逻辑器件。它不仅能记录输入时钟脉冲的个数,还可以实现
    发表于 03-08 13:16 3.1w次阅读

    二进制电平,什么是二进制电平

    二进制电平,什么是二进制电平 在二进制数字通信系统中,每个码元或每个符号只能是“1”和“0”两个状态之一。若将每个码元可能取的状态增
    发表于 03-17 16:51 2359次阅读

    二进制加法程序【汇编版】

    二进制加法程序【汇编版】二进制加法程序【汇编版】二进制加法程序【汇编版】二进制加法程序【汇编版】
    发表于 12-29 11:02 0次下载

    二进制加法程序【C语言版】

    二进制加法程序【C语言版】二进制加法程序【C语言版】二进制加法程序【C语言版】二进制加法程序【C语言版】
    发表于 12-29 11:03 0次下载

    二进制数据压缩算法

    二进制数据压缩算法二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢
    的头像 发表于 02-28 09:31 2w次阅读

    二进制解码器案例说明

    二进制解码器是另一种由各个逻辑门构成的组合逻辑电路,与编码器完全相反。
    的头像 发表于 06-22 09:41 9369次阅读
    <b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器案例说明

    二进制解码器到底是什么

    二进制解码器是由单独的逻辑门构成的另一种组合逻辑电路,与编码器完全相反。名称“解码器”是指将编码信息从一种格式转换或解码为另一种格式,因此二进制
    发表于 01-03 17:42 6244次阅读
    <b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器到底是什么

    二进制解码器开源设计

    电子发烧友网站提供《二进制解码器开源设计.zip》资料免费下载
    发表于 06-16 15:01 0次下载
    <b class='flag-5'>二进制</b><b class='flag-5'>解码</b>器开源设计