久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

開源點(diǎn)評:Protocol Buffers介紹

 思考的軌跡 2011-12-01

開源點(diǎn)評:Protocol Buffers介紹


  今天來介紹一下“Protocol Buffers”(以下簡稱protobuf)這個(gè)玩意兒。本來俺在構(gòu)思“生產(chǎn)者/消費(fèi)者模式 ”系列的下一個(gè)帖子:關(guān)于生產(chǎn)者和消費(fèi)者之間的數(shù)據(jù)傳輸格式,。由于里面扯到了protobuf,,想想干脆單獨(dú)開一個(gè)帖子算了。

  ★protobuf是啥玩意兒,?
  為了照顧從沒聽說過的同學(xué),,照例先來掃盲一把。
  首先,,protobuf是一個(gè)開源項(xiàng)目(官方站點(diǎn)在“這里 ”),,而且是后臺很硬的開源項(xiàng)目。網(wǎng)上現(xiàn)有的大部分(至少80%)開源項(xiàng)目,,要么是某人單干,、要么是幾個(gè)閑雜人等合伙搞。而protobuf則不然,,它是鼎鼎大名的Google公司開發(fā)出來,,并且在Google內(nèi)部久經(jīng)考驗(yàn)的一個(gè)東東。由此可見,,它的作者絕非一般閑雜人等可比,。
  那這個(gè)聽起來牛X的東東到底有啥用處捏?簡單地說,,這個(gè)東東干的事兒其實(shí)和XML差不多,,也就是把某種數(shù)據(jù)結(jié)構(gòu)的信息,以某種格式保存起來,。主要用于數(shù)據(jù)存儲,、傳輸協(xié)議格式等 場合。有同學(xué)可能心理犯嘀咕了:放著好好的XML不用,,干嘛重新發(fā)明輪子?。?!先別急,,后面俺自然會有說道。
  話說到了去年(大約是08年7 月),,Google突然大發(fā)慈悲,,把這個(gè)好東西貢獻(xiàn)給了開源社區(qū)。這下,,像俺這種喜歡撿現(xiàn)成的家伙可就有福啦,!貌似喜歡撿現(xiàn)成的家伙還蠻多滴,,再加上Google的號召力,開源后不到一年,,protobuf的人氣就已經(jīng)很旺了,。所以俺為了與時(shí)俱進(jìn),就單獨(dú)開個(gè)帖子來忽悠一把,。

  ★protobuf有啥特色,?
  掃盲完了之后,就該聊一下技術(shù)方面的話題了,。由于這玩意兒發(fā)布的時(shí)間較短(未滿周歲),,所以俺接觸的時(shí)間也不長。今天在此是先學(xué)現(xiàn)賣,,列位看官多多包涵 :-)

  ◇性能好/效率高
  現(xiàn)在,,俺就來說說Google公司為啥放著好端端的XML不用,非要另起爐灶,,重新造輪子,。一個(gè)根本的原因是XML性能不夠好。
  先說時(shí)間開銷:XML格式化(序列化)的開銷倒還好,;但是XML解析(反序列化)的開銷就不敢恭維啦,。俺之前經(jīng)常碰到一些時(shí)間性能很敏感的場合,由于不堪忍受XML解析的速度,,棄之如敝履,。
  再來看空間開銷:熟悉XML語法的同學(xué)應(yīng)該知道,XML格式為了有較好的可讀性,,引入了一些冗余的文本信息,。所以空間開銷也不是太好(不過這點(diǎn)缺點(diǎn),俺不常碰到),。
   由于Google公司賴以吹噓的就是它的海量數(shù)據(jù)和海量處理能力,。對于幾十萬、上百萬機(jī)器的集群,,動不動就是PB級的數(shù)據(jù)量,,哪怕性能稍微提高0.1%也是相當(dāng)可觀滴。所以Google自然無法容忍XML在性能上的明顯缺點(diǎn),。再加上Google從來就不缺造輪子的牛人,,所以protobuf也就應(yīng)運(yùn)而生了。
  Google對于性能的偏執(zhí),,那可是出了名的,。所以,俺對于Google搞出來protobuf是非常滴放心,,性能上不敢說是最好,,但肯定不會太差。

  ◇代碼生成機(jī)制
  除了性能好,,代碼生成機(jī)制是主要吸引俺的地方,。為了說明這個(gè)代碼生成機(jī)制,俺舉個(gè)例子,。
  比如有個(gè)電子商務(wù)的系統(tǒng)(假設(shè)用C++實(shí)現(xiàn)),,其中的模塊A需要發(fā)送大量的訂單信息給模塊B,通訊的方式使用socket,。
假設(shè)訂單包括如下屬性:
--------------------------------
  時(shí)間:time(用整數(shù)表示)
  客戶id:userid(用整數(shù)表示)
  交易金額:price(用浮點(diǎn)數(shù)表示)
  交易的描述:desc(用字符串表示)
--------------------------------
  如果使用protobuf實(shí)現(xiàn),,首先要寫一個(gè)proto文件(不妨叫Order.proto),在該文件中添加一個(gè)名為"Order"的message結(jié)構(gòu),,用來描述通訊協(xié)議中的結(jié)構(gòu)化數(shù)據(jù),。該文件的內(nèi)容大致如下:


--------------------------------
message Order
{
  required int32 time = 1;
  required int32 userid = 2;
  required float price = 3;
  optional string desc = 4;
}
--------------------------------

  然后,使用protobuf內(nèi)置的編譯器編譯 該proto,。由于本例子的模塊是C++,,你可以通過protobuf編譯器的命令行參數(shù)(看“這里 ”),指定它生成C++語言的“訂單包裝類”,。(一般來說,,一個(gè)message結(jié)構(gòu)會生成一個(gè)包裝類)
  然后你使用類似下面的代碼來序列化/解析該訂單包裝類:


--------------------------------
// 發(fā)送方
Order order;
order.set_time(XXXX);
order.set_userid(123);
order.set_price(100.0f);
order.set_desc("a test order");

string sOrder;
order.SerailzeToString(&sOrder);
// 然后調(diào)用某種socket的通訊庫把序列化之后的字符串發(fā)送出去
// ......

--------------------------------
// 接收方
string sOrder;
// 先通過網(wǎng)絡(luò)通訊庫接收到數(shù)據(jù),存放到某字符串sOrder
// ......

Order order;
if(order.ParseFromString(sOrder)) // 解析該字符串
{
  cout << "userid:" << order.userid() << endl
  << "desc:" << order.desc() << endl;
}
else
{
  cerr << "parse error!" << endl;
}
--------------------------------

  有了這種代碼生成機(jī)制,,開發(fā)人員再也不用吭哧吭哧地編寫那些協(xié)議解析的代碼了(干這種活是典型的吃力不討好),。
  萬一將來需求發(fā)生變更,要求給訂單再增加一個(gè)“狀態(tài)”的屬性,,那只需要在Order.proto文件中增加一行代碼,。對于發(fā)送方(模塊A),只要增加一行設(shè)置狀態(tài)的代碼,;對于接收方(模塊B)只要增加一行讀取狀態(tài)的代碼,。哇塞,簡直太輕松了,!
  另外,,如果通訊雙方使用不同的編程語言來實(shí)現(xiàn),使用這種機(jī)制可以有效確保兩邊的模塊對于協(xié)議的處理是一致的,。
  順便跑題一下,。
  從某種意義上講,可以把proto文件看成是描述通訊協(xié)議的規(guī)格說明書(或者叫接口規(guī)范),。這種伎倆其實(shí)老早就有了,,搞過微軟的COM編程或者接觸過CORBA的同學(xué),應(yīng)該都能從中看到IDL(詳細(xì)解釋看“這里 ”)的影子。它們的思想是相通滴,。

  ◇支持“向后兼容”和“向前兼容”
  還是拿剛才的例子來說事兒,。為了敘述方便,俺把增加了“狀態(tài)”屬性的訂單協(xié)議成為“新版本”,;之前的叫“老版本”,。
  所謂的“向后兼容”(backward compatible),就是說,,當(dāng)模塊B升級了之后,,它能夠正確識別模塊A發(fā)出的老版本的協(xié)議。由于老版本沒有“狀態(tài)”這個(gè)屬性,,在擴(kuò)充協(xié)議時(shí),,可以考慮把“狀態(tài)”屬性設(shè)置成非必填 的,或者給“狀態(tài)”屬性設(shè)置一個(gè)缺省值(如何設(shè)置缺省值,,參見“這里 ”),。
  所謂的“向前兼容”(forward compatible),就是說,,當(dāng)模塊A升級了之后,,模塊B能夠正常識別模塊A發(fā)出的新版本的協(xié)議。這時(shí)候,,新增加的“狀態(tài)”屬性會被忽略,。
  “向后兼容”和“向前兼容”有啥用捏?俺舉個(gè)例子:當(dāng)你維護(hù)一個(gè)很龐大的分布式系統(tǒng)時(shí),,由于你無法同時(shí) 升級所有 模塊,,為了保證在升級過程中,整個(gè)系統(tǒng)能夠盡可能不受影響,,就需要盡量保證通訊協(xié)議的“向后兼容”或“向前兼容”,。

  ◇支持多種編程語言
  俺開博以來點(diǎn)評的幾個(gè)開源項(xiàng)目(比如“Sqlite ”、“cURL ”),,都是支持很多種 編程語言滴,,這次的protobuf也不例外。在Google官方發(fā)布的源代碼中包含了C++,、Java,、Python三種語言(正好也是俺最常用的三種,真爽),。如果你平時(shí)用的就是這三種語言之一,,那就好辦了。
  假如你想把protobuf用于其它語言,,咋辦捏,?由于Google一呼百應(yīng)的號召力,,開源社區(qū)對protobuf響應(yīng)踴躍,近期冒出很多其它編程語言 的版本(比如ActionScript,、C#,、Lisp、Erlang,、Perl,、PHP,、Ruby等),,有些語言還同時(shí)搞出了多個(gè)開源的項(xiàng)目。具體細(xì)節(jié)可以參見“這里 ”,。
  不過俺有義務(wù)提醒一下在座的各位同學(xué),。如果你考慮把protobuf用于上述這些語言,一定認(rèn)真評估對應(yīng)的開源庫,。因?yàn)檫@些開源庫不是Google官方提供的,、而且出來的時(shí)間還不長。所以,,它們的質(zhì)量,、性能等方面可能還有欠缺。

  ★protobuf有啥缺陷,?
  前幾天剛剛在“光環(huán)效應(yīng) ”的帖子里強(qiáng)調(diào)了“要同時(shí)評估優(yōu)點(diǎn)和缺點(diǎn)”,。所以俺最后再來批判一下這玩意兒的缺點(diǎn)。
  ◇應(yīng)用不夠廣
  由于protobuf剛公布沒多久,,相比XML而言,,protobuf還屬于初出茅廬。因此,,在知名度,、應(yīng)用廣度等方面都遠(yuǎn)不如XML。由于這個(gè)原因,,假如你設(shè)計(jì)的系統(tǒng)需要提供若干對外的接口給第三方系統(tǒng)調(diào)用,,俺奉勸你暫時(shí)不要考慮protobuf格式。
  ◇二進(jìn)制格式導(dǎo)致可讀性差
  為了提高性能,,protobuf采用了二進(jìn)制格式進(jìn)行編碼,。這直接導(dǎo)致了可讀性差的問題(嚴(yán)格地說,是沒有可讀性),。雖然protobuf提供了TextFormat這個(gè)工具類(文檔在“這里 ”),,但終究無法徹底解決此問題。
   可讀性差的危害,,俺再來舉個(gè)例子,。比如通訊雙方如果出現(xiàn)問題,極易導(dǎo)致扯皮(都不承認(rèn)自己有問題,都說是對方的錯(cuò)),。俺對付扯皮的一個(gè)簡單方法就是直接抓包并dump成log,,能比較容易地看出錯(cuò)誤在哪一方。但是protobuf的二進(jìn)制格式,,導(dǎo)致你抓包并直接dump出來的log難以看懂,。
  ◇缺乏自描述
  一般來說,XML是自描述的,,而protobuf格式則不是,。給你一段二進(jìn)制格式的協(xié)議內(nèi)容,如果不配合相應(yīng)的proto文件,,那簡直就像天書一般,。
  由于“缺乏自描述”,再加上“二進(jìn)制格式導(dǎo)致可讀性差”,。所以在配置文件方面,,protobuf是肯定無法取代XML的地位滴。

  ★為什么俺會用上protobuf,?
  俺自從前段時(shí)間接觸了protobuf之后,,就著手把俺負(fù)責(zé)的產(chǎn)品中的部分 數(shù)據(jù)傳輸協(xié)議替換成protobuf??赡苡型瑢W(xué)會問,,和protobuf類似的東東也有不少,為啥獨(dú)獨(dú)相中protobuf捏,?由于今天寫的篇幅已經(jīng)蠻長了,,俺賣個(gè)關(guān)子,把這個(gè)話題留到“生產(chǎn)者/消費(fèi)者模式[5]:如何選擇傳輸協(xié)議及格式,?”,。俺會在后續(xù)的這個(gè)帖子里對比各種五花八門的協(xié)議格式,并談?wù)劙车臏\見,。


版權(quán)聲明
本博客所有的原創(chuàng)文章,,作者皆保留版權(quán)。轉(zhuǎn)載必須包含本聲明,,保持本文完整,,并以超鏈接形式注明作者編程隨想 和本文原始地址:

http://program-think./2009/05/opensource-review-protocol-buffers.html

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多