0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深入剖析ProtoBuf原理與工程實(shí)踐

Linux愛好者 ? 來源:vivo互聯(lián)網(wǎng)技術(shù) ? 作者:Li Guanyun ? 2021-11-16 09:15 ? 次閱讀

ProtoBuf 作為一種跨平臺(tái)、語言無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)的方法,已廣泛應(yīng)用于網(wǎng)絡(luò)數(shù)據(jù)交換及存儲(chǔ)。隨著互聯(lián)網(wǎng)的發(fā)展,系統(tǒng)的異構(gòu)性會(huì)愈發(fā)突出,跨語言的需求會(huì)愈加明顯,同時(shí) gRPC 也大有取代Restful之勢(shì),而 ProtoBuf 作為g RPC 跨語言、高性能的法寶,我們技術(shù)人有必要

深入理解 ProtoBuf 原理,為以后的技術(shù)更新和選型打下基礎(chǔ)。

我將過去的學(xué)習(xí)過程以及實(shí)踐經(jīng)驗(yàn),總結(jié)成系列文章,與大家一起探討學(xué)習(xí),希望大家能有所收獲,當(dāng)然其中有不正確的地方也歡迎大家批評(píng)指正。

一、什么是ProtoBuf

ProtoBuf(Protocol Buffers)是一種跨平臺(tái)、語言無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)的方法,可用于網(wǎng)絡(luò)數(shù)據(jù)交換及存儲(chǔ)。

在序列化結(jié)構(gòu)化數(shù)據(jù)的機(jī)制中,ProtoBuf是靈活、高效、自動(dòng)化的,相對(duì)常見的XML、JSON,描述同樣的信息,ProtoBuf序列化后數(shù)據(jù)量更小、序列化/反序列化速度更快、更簡(jiǎn)單。

一旦定義了要處理的數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)之后,就可以利用ProtoBuf的代碼生成工具生成相關(guān)的代碼。只需使用 Protobuf 對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行一次描述,即可利用各種不同語言(proto3支持C++, Java, Python, Go, Ruby, Objective-C, C#)或從各種不同流中對(duì)你的結(jié)構(gòu)化數(shù)據(jù)輕松讀寫。

二、為什么是 ProtoBuf

大家可能會(huì)覺得 Google 發(fā)明 ProtoBuf 是為了解決序列化速度的,其實(shí)真實(shí)的原因并不是這樣的。

ProtoBuf最先開始是 Google用來解決索引服務(wù)器 request/response 協(xié)議的。沒有ProtoBuf之前,Google 已經(jīng)存在了一種 request/response 格式,用于手動(dòng)處理 request/response 的編解碼。它也能支持多版本協(xié)議,不過代碼不夠優(yōu)雅:

if(protocolVersion=1){
doSomething();
}elseif(protocolVersion=2){
doOtherThing();
}...

如果是非常明確的格式化協(xié)議,會(huì)使新協(xié)議變得非常復(fù)雜。因?yàn)殚_發(fā)人員必須確保請(qǐng)求發(fā)起者與處理請(qǐng)求的實(shí)際服務(wù)器之間的所有服務(wù)器都能理解新協(xié)議,然后才能切換開關(guān)以開始使用新協(xié)議。

這也就是每個(gè)服務(wù)器開發(fā)人員都遇到過的低版本兼容、新舊協(xié)議兼容相關(guān)的問題。

為了解決這些問題,于是ProtoBuf就誕生了。

ProtoBuf 最初被寄予以下 2 個(gè)特點(diǎn):

  • 更容易引入新的字段,并且不需要檢查數(shù)據(jù)的中間服務(wù)器可以簡(jiǎn)單地解析并傳遞數(shù)據(jù),而無需了解所有字段。
  • 數(shù)據(jù)格式更加具有自我描述性,可以用各種語言來處理(C++, Java 等各種語言)。

這個(gè)版本的 ProtoBuf 仍需要自己手寫解析的代碼。

不過隨著系統(tǒng)慢慢發(fā)展,演進(jìn),ProtoBuf具有了更多的特性:

  • 自動(dòng)生成的序列化和反序列化代碼避免了手動(dòng)解析的需要。(官方提供自動(dòng)生成代碼工具,各個(gè)語言平臺(tái)的基本都有)。
  • 除了用于數(shù)據(jù)交換之外,ProtoBuf被用作持久化數(shù)據(jù)的便捷自描述格式。

ProtoBuf 現(xiàn)在是 Google 用于數(shù)據(jù)交換和存儲(chǔ)的通用語言。谷歌代碼樹中定義了 48162 種不同的消息類型,包括 12183 個(gè) .proto 文件。它們既用于 RPC 系統(tǒng),也用于在各種存儲(chǔ)系統(tǒng)中持久存儲(chǔ)數(shù)據(jù)。

ProtoBuf 誕生之初是為了解決服務(wù)器端新舊協(xié)議(高低版本)兼容性問題,名字也很體貼,“協(xié)議緩沖區(qū)”。只不過后期慢慢發(fā)展成用于傳輸數(shù)據(jù)。

Protocol Buffers 命名由來:

Why the name "Protocol Buffers"?

The name originates from the early days of the format, before we had the protocol buffer compiler to generate classes for us. At the time, there was a class called ProtocolBuffer which actually acted as a buffer for an individual method. Users would add tag/value pairs to this buffer individually by calling methods like AddValue(tag, value). The raw bytes were stored in a buffer which could then be written out once the message had been constructed.

Since that time, the "buffers" part of the name has lost its meaning, but it is still the name we use. Today, people usually use the term "protocol message" to refer to a message in an abstract sense, "protocol buffer" to refer to a serialized copy of a message, and "protocol message object" to refer to an in-memory object representing the parsed message.

三、如何使用 ProtoBuf

3.1 ProtoBuf 協(xié)議的工作流程

可以看到,對(duì)于序列化協(xié)議來說,使用方只需要關(guān)注業(yè)務(wù)對(duì)象本身,即 idl 定義,序列化和反序列化的代碼只需要通過工具生成即可。

3.2 ProtoBuf 消息定義

ProtoBuf 的消息是在idl文件(.proto)中描述的。下面是本次樣例中使用到的消息描述符customer.proto:

syntax="proto3";

packagedomain;

optionjava_package="com.protobuf.generated.domain";
optionjava_outer_classname="CustomerProtos";

messageCustomers{
repeatedCustomercustomer=1;
}

messageCustomer{
int32id=1;
stringfirstName=2;
stringlastName=3;

enumEmailType{
PRIVATE=0;
PROFESSIONAL=1;
}

messageEmailAddress{
stringemail=1;
EmailTypetype=2;
}

repeatedEmailAddressemail=5;
}

上面的消息比較簡(jiǎn)單,Customers包含多個(gè)Customer,Customer包含一個(gè)id字段,一個(gè)firstName字段,一個(gè)lastName字段以及一個(gè)email的集合。

除了這些定義外,文件頂部還有三行可幫助代碼生成器:

  1. 首先,syntax = "proto3"用于idl語法版本,目前有兩個(gè)版本proto2和proto3,兩個(gè)版本語法不兼容,如果不指定,默認(rèn)語法是proto2。由于proto3比proto2支持的語言更多,語法更簡(jiǎn)潔,本文使用的是proto3。

  2. 其次有一個(gè)package domain;定義。此配置用于嵌套生成的類/對(duì)象。

  3. 有一個(gè)option java_package定義。生成器還使用此配置來嵌套生成的源。此處的區(qū)別在于這僅適用于Java。在使用Java創(chuàng)建代碼和使用JavaScript創(chuàng)建代碼時(shí),使用了兩種配置來使生成器的行為有所不同。也就是說,Java類是在包c(diǎn)om.protobuf.generated.domain下創(chuàng)建的,而JavaScript對(duì)象是在包domain下創(chuàng)建的。

ProtoBuf 提供了更多選項(xiàng)和數(shù)據(jù)類型,本文不做詳細(xì)介紹,感興趣可以參考這里[1]。

3.3 代碼生成

首先安裝 ProtoBuf 編譯器 protoc,這里[2]有詳細(xì)的安裝教程,安裝完成后,可以使用以下命令生成 Java 源代碼:

protoc--java_out=./src/main/java./src/main/idl/customer.proto

從項(xiàng)目的根路徑執(zhí)行該命令,并添加了兩個(gè)參數(shù):java_out,定義./src/main/java/為Java代碼的輸出目錄;而./src/main/idl/customer.proto是.proto文件所在目錄。

生成的代碼非常復(fù)雜,但是幸運(yùn)的是它的用法卻非常簡(jiǎn)單。

CustomerProtos.Customer.EmailAddressemail=CustomerProtos.Customer.EmailAddress.newBuilder()
.setType(CustomerProtos.Customer.EmailType.PROFESSIONAL)
.setEmail("crichardson@email.com").build();

CustomerProtos.Customercustomer=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.CustomeranotherCustomer=CustomerProtos.Customer.parseFrom(binaryInfo);
System.out.println(anotherCustomer.toString());

3.4 性能數(shù)據(jù)

我們簡(jiǎn)單地以Customers為模型,分別構(gòu)造、選取小對(duì)象、普通對(duì)象、大對(duì)象進(jìn)行性能對(duì)比。

序列化耗時(shí)以及序列化后數(shù)據(jù)大小對(duì)比

反序列化耗時(shí)

c8f14736-44ef-11ec-b939-dac502259ad0.png

更多性能數(shù)據(jù)可以參考官方 Benchmark[3]

四、總結(jié)

上面介紹了 ProtoBuf 是什么、產(chǎn)生的背景、基本用法,我們?cè)倏偨Y(jié)下。

優(yōu)點(diǎn):

1. 效率高

從序列化后的數(shù)據(jù)體積角度,與XML、JSON這類文本協(xié)議相比,ProtoBuf通過T-(L)-V(TAG-LENGTH-VALUE)方式編碼,不需要", {, }, :等分隔符來結(jié)構(gòu)化信息,同時(shí)在編碼層面使用varint壓縮,所以描述同樣的信息,ProtoBuf序列化后的體積要小很多,在網(wǎng)絡(luò)中傳輸消耗的網(wǎng)絡(luò)流量更少,進(jìn)而對(duì)于網(wǎng)絡(luò)資源緊張、性能要求非常高的場(chǎng)景,ProtoBuf協(xié)議是不錯(cuò)的選擇。

//我們簡(jiǎn)單做個(gè)對(duì)比
//要描述如下JSON數(shù)據(jù)
{"id":1,"firstName":"Chris","lastName":"Richardson","email":[{"type":"PROFESSIONAL","email":"crichardson@email.com"}]}
#使用JSON序列化后的數(shù)據(jù)大小為118byte
7b226964223a312c2266697273744e616d65223a224368726973222c226c6173744e616d65223a2252696368617264736f6e222c22656d61696c223a5b7b2274797065223a2250524f46455353494f4e414c222c22656d61696c223a226372696368617264736f6e40656d61696c2e636f6d227d5d7d
#而使用ProtoBuf序列化后的數(shù)據(jù)大小為48byte
0801120543687269731a0a52696368617264736f6e2a190a156372696368617264736f6e40656d61696c2e636f6d1001

從序列化/反序列化速度角度,與XML、JSON相比,ProtoBuf序列化/反序列化的速度更快,比XML要快20-100倍。

2. 支持跨平臺(tái)、多語言

ProtoBuf是平臺(tái)無關(guān)的,無論是Android與PC,還是C#與Java都可以利用ProtoBuf進(jìn)行無障礙通訊。

proto3支持C++, Java, Python, Go, Ruby, Objective-C, C#。

3. 擴(kuò)展性、兼容性好

具有向后兼容的特性,更新數(shù)據(jù)結(jié)構(gòu)以后,老版本依舊可以兼容,這也是ProtoBuf誕生之初被寄予解決的問題。因?yàn)榫幾g器對(duì)不識(shí)別的新增字段會(huì)跳過不處理。

4. 使用簡(jiǎn)單

ProtoBuf 提供了一套編譯工具,可以自動(dòng)生成序列化、反序列化的樣板代碼,這樣開發(fā)者只要關(guān)注業(yè)務(wù)數(shù)據(jù)idl,簡(jiǎn)化了編碼解碼工作以及多語言交互的復(fù)雜度。

缺點(diǎn)

可讀性差,缺乏自描述

XML,JSON是自描述的,而ProtoBuf則不是。

ProtoBuf是二進(jìn)制協(xié)議,編碼后的數(shù)據(jù)可讀性差,如果沒有idl文件,就無法理解二進(jìn)制數(shù)據(jù)流,對(duì)調(diào)試不友好。

不過Charles已經(jīng)支持ProtoBuf協(xié)議,導(dǎo)入數(shù)據(jù)的描述文件即可,詳情可參考Charles Protocol Buffers[4]。

此外,由于沒有idl文件無法解析二進(jìn)制數(shù)據(jù)流,ProtoBuf在一定程度上可以保護(hù)數(shù)據(jù),提升核心數(shù)據(jù)被破解的門檻,降低核心數(shù)據(jù)被盜爬的風(fēng)險(xiǎn)。

編輯:jq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • XML
    XML
    +關(guān)注

    關(guān)注

    0

    文章

    188

    瀏覽量

    33105
  • 編碼
    +關(guān)注

    關(guān)注

    6

    文章

    952

    瀏覽量

    54890
  • JSON
    +關(guān)注

    關(guān)注

    0

    文章

    119

    瀏覽量

    6987

原文標(biāo)題:深入理解 ProtoBuf 原理與工程實(shí)踐(概述)

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    微軟發(fā)布《GraphRAG實(shí)踐應(yīng)用白皮書》助力開發(fā)者

    了其概述、表示、存儲(chǔ)、查詢與抽取方法,為讀者打下了堅(jiān)實(shí)的理論基礎(chǔ)。隨后,白皮書深入剖析了GraphRAG的整體架構(gòu)、實(shí)踐挑戰(zhàn)以及圖形化展示,并結(jié)合Agentic RAG所面臨的難題,提出了切實(shí)可行的應(yīng)對(duì)方案。 此外,白皮書還通過
    的頭像 發(fā)表于 01-13 16:11 ?234次閱讀

    深入剖析半導(dǎo)體濕法刻蝕過程中殘留物形成的機(jī)理

    半導(dǎo)體濕法刻蝕過程中殘留物的形成,其背后的機(jī)制涵蓋了化學(xué)反應(yīng)、表面交互作用以及側(cè)壁防護(hù)等多個(gè)層面,下面是對(duì)這些機(jī)制的深入剖析: 化學(xué)反應(yīng)層面 1 刻蝕劑與半導(dǎo)體材料的交互:濕法刻蝕技術(shù)依賴于特定
    的頭像 發(fā)表于 01-08 16:57 ?254次閱讀

    夢(mèng)之墨創(chuàng)新工程教育實(shí)踐套件家族再添一員

    在電子信息工程教育領(lǐng)域,理論與實(shí)踐相結(jié)合的教學(xué)模式正日益受到重視。近期,夢(mèng)之墨創(chuàng)新工程教育實(shí)踐套件家族再添一員,即基于電子增材制造技術(shù)與電子工程
    的頭像 發(fā)表于 01-02 10:37 ?103次閱讀

    BNC接頭技術(shù)原理與工程應(yīng)用剖析:從結(jié)構(gòu)到性能優(yōu)化

    在現(xiàn)代電子通信和射頻領(lǐng)域,BNC接頭作為一種廣泛應(yīng)用的連接器件,發(fā)揮著至關(guān)重要的作用。它以其可靠的連接性能、優(yōu)異的電氣特性和廣泛的兼容性,成為眾多電子設(shè)備和系統(tǒng)中不可或缺的一部分。本文將深入剖析
    的頭像 發(fā)表于 12-31 16:07 ?208次閱讀
    BNC接頭技術(shù)原理與<b class='flag-5'>工程</b>應(yīng)用<b class='flag-5'>剖析</b>:從結(jié)構(gòu)到性能優(yōu)化

    深入剖析2.5D封裝技術(shù)優(yōu)勢(shì)及應(yīng)用

    的一項(xiàng)重要?jiǎng)?chuàng)新,不僅提高了芯片的性能和集成度,還為未來的芯片設(shè)計(jì)提供了更多的可能性。本文將深入剖析2.5D封裝技術(shù)的內(nèi)涵、優(yōu)勢(shì)及其在現(xiàn)代半導(dǎo)體工業(yè)中的應(yīng)用。 一、芯片封裝的重要性 封裝作為半導(dǎo)體制造流程中的關(guān)鍵環(huán)節(jié),其核心作用在
    的頭像 發(fā)表于 11-22 09:12 ?1368次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>剖析</b>2.5D封裝技術(shù)優(yōu)勢(shì)及應(yīng)用

    精確溫控技術(shù)在焊接電源中的應(yīng)用與實(shí)踐探析

    節(jié)能等方面都起到了決定性的作用。以下將對(duì)精確溫控技術(shù)在焊接電源中的應(yīng)用與實(shí)踐進(jìn)行深入剖析。 首先,精確溫控技術(shù)是現(xiàn)代焊接電源的核心組成部分之一。焊接過程中,溫度控
    的頭像 發(fā)表于 11-19 09:08 ?246次閱讀
    精確溫控技術(shù)在焊接電源中的應(yīng)用與<b class='flag-5'>實(shí)踐</b>探析

    深入剖析石英 CMOS 振蕩器 PC3225 系列(1 to 200 MHz)的卓越性能

    深入剖析石英 CMOS 振蕩器 PC3225 系列(1 to 200 MHz)的卓越性能
    的頭像 發(fā)表于 08-08 10:14 ?388次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>剖析</b>石英 CMOS 振蕩器 PC3225 系列(1 to 200 MHz)的卓越性能

    熱烈歡迎清華大學(xué)電子工程系學(xué)子來武漢六博光電交流實(shí)踐!

    近日,武漢六博光電技術(shù)有限責(zé)任公司接到清華大學(xué)函件,正式成為清華大學(xué)電子工程系武漢實(shí)踐基地之一。2024年8月1日上午,清華大學(xué)電子工程實(shí)踐團(tuán)隊(duì)一行共計(jì)13名學(xué)子前往武漢六博光電有限
    的頭像 發(fā)表于 08-02 08:37 ?540次閱讀
    熱烈歡迎清華大學(xué)電子<b class='flag-5'>工程</b>系學(xué)子來武漢六博光電交流<b class='flag-5'>實(shí)踐</b>!

    振弦采集儀的工程安全監(jiān)測(cè)實(shí)踐與案例分析

    振弦采集儀的工程安全監(jiān)測(cè)實(shí)踐與案例分析 振弦采集儀是一種常用的工程安全監(jiān)測(cè)儀器,通過測(cè)量被監(jiān)測(cè)結(jié)構(gòu)的振動(dòng)頻率與振型,可以實(shí)時(shí)監(jiān)測(cè)結(jié)構(gòu)的安全狀況。本文將結(jié)合實(shí)踐經(jīng)驗(yàn)和案例分析,探討振弦采
    的頭像 發(fā)表于 07-01 11:01 ?269次閱讀
    振弦采集儀的<b class='flag-5'>工程</b>安全監(jiān)測(cè)<b class='flag-5'>實(shí)踐</b>與案例分析

    深入剖析“復(fù)坦希UVLED固化爐”的工作原理與技術(shù)創(chuàng)新

    在現(xiàn)代工業(yè)制造中,UV固化技術(shù)因其高效、環(huán)保的特點(diǎn)而受到廣泛關(guān)注。在眾多UV固化設(shè)備中,“復(fù)坦希UVLED固化爐”憑借其獨(dú)特的工作原理和卓越的技術(shù)創(chuàng)新,成為行業(yè)內(nèi)的佼佼者。本文將深入剖析這款設(shè)備
    的頭像 發(fā)表于 05-28 14:32 ?511次閱讀

    【大語言模型:原理與工程實(shí)踐】探索《大語言模型原理與工程實(shí)踐》2.0

    《大語言模型“原理與工程實(shí)踐”》是關(guān)于大語言模型內(nèi)在機(jī)理和應(yīng)用實(shí)踐的一次深入探索。作者不僅深入討論了理論,還提供了豐富的
    發(fā)表于 05-07 10:30

    【大語言模型:原理與工程實(shí)踐】探索《大語言模型原理與工程實(shí)踐

    的未來發(fā)展方向進(jìn)行了展望,包括跨領(lǐng)域、跨模態(tài)和自動(dòng)提示生成能力方向,為讀者提供了對(duì)未來技術(shù)發(fā)展的深刻見解?!洞笳Z言模型原理與工程實(shí)踐》是一本內(nèi)容豐富、深入淺出的技術(shù)書籍。它不僅為讀者提供了大語言模型
    發(fā)表于 04-30 15:35

    振弦采集儀在橋梁工程監(jiān)測(cè)中的優(yōu)勢(shì)與實(shí)踐案例

    振弦采集儀在橋梁工程監(jiān)測(cè)中的優(yōu)勢(shì)與實(shí)踐案例 在橋梁工程監(jiān)測(cè)中,振弦采集儀是一種常用的監(jiān)測(cè)設(shè)備。它的主要功能是通過采集橋梁振動(dòng)信號(hào),實(shí)時(shí)監(jiān)測(cè)橋梁的結(jié)構(gòu)健康狀態(tài)。與傳統(tǒng)的監(jiān)測(cè)方法相比,振弦采集儀具有一些
    的頭像 發(fā)表于 04-01 14:03 ?305次閱讀
    振弦采集儀在橋梁<b class='flag-5'>工程</b>監(jiān)測(cè)中的優(yōu)勢(shì)與<b class='flag-5'>實(shí)踐</b>案例

    深入剖析電機(jī)產(chǎn)品的實(shí)際槽滿率問題

    本篇文章深入剖析電機(jī)產(chǎn)品的實(shí)際槽滿率問題。需要注意的是,存在一種由于生產(chǎn)限制而降低的槽滿率,這主要出現(xiàn)在使用針嘴式繞線機(jī)的電機(jī)中,因?yàn)檫@種設(shè)備需要預(yù)留針嘴操作的空間。? 槽滿率的高低對(duì)電機(jī)的效率有
    的頭像 發(fā)表于 03-26 08:44 ?572次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>剖析</b>電機(jī)產(chǎn)品的實(shí)際槽滿率問題

    名單公布!【書籍評(píng)測(cè)活動(dòng)NO.31】大語言模型:原理與工程實(shí)踐

    深入理解和廣泛應(yīng)用,推動(dòng)整個(gè)領(lǐng)域的持續(xù)發(fā)展和創(chuàng)新。 本書特色 本書旨在揭開大語言模型的神秘面紗,透徹地解讀其內(nèi)在機(jī)理和應(yīng)用實(shí)踐。書中不僅介紹理論知識(shí),更介紹了深入這一技術(shù)領(lǐng)域的具體訓(xùn)練過程,目的是為
    發(fā)表于 03-18 15:49