幾種常見的序列化和反序列化協議

互聯網早期的序列化協議主要有COM和CORBA。

       COM主要用於Windows平臺,並沒有真正實現跨平臺,另外COM的序列化的原理利用了編譯器中虛表,使得其學習成本巨大(想一下這個場景, 工程師需要是簡單的序列化協議,但卻要先掌握語言編譯器)。由於序列化的數據與編譯器緊耦合,擴展屬性非常麻煩。

       CORBA 是早期比較好的實現了跨平臺,跨語言的序列化協議。COBRA的主要問題是參與方過多帶來的版本過多,版本之間兼容性較差,以及使用複雜晦澀。這些政治經 濟,技術實現以及早期設計不成熟的問題,最終導致COBRA的漸漸消亡。J2SE 1.3之後的版本提供了基於CORBA協議的RMI-IIOP技術,這使得Java開發者可以採用純粹的Java語言進行CORBA的開發。

這裏主要介紹和對比幾種當下比較流行的序列化協議,包括XML、JSON、Protobuf、Thrift和Avro。

XML&SOAP

       XML 是一種常用的序列化和反序列化協議,具有跨機器,跨語言等優點。 XML歷史悠久,其1.0版本早在1998年就形成標準,並被廣泛使用至今。XML的最初產生目標是對互聯網文檔(Document)進行標記,所以它的 設計理念中就包含了對於人和機器都具備可讀性。 但是,當這種標記文檔的設計被用來序列化對象的時候,就顯得冗長而複雜(Verbose and Complex)。 XML本質上是一種描述語言,並且具有自我描述(Self-describing)的屬性,所以XML自身就被用於XML序列化的IDL。 標準的XML描述格式有兩種:DTD(Document Type Definition)和XSD(XML Schema Definition)。作爲一種人眼可讀(Human-readable)的描述語言,XML被廣泛使用在配置文件中,例如O/R mapping、 Spring Bean Configuration File 等。

SOAP(Simple Object Access protocol) 是一種被廣泛應用的,基於XML爲序列化和反序列化協議的結構化消息傳遞協議。SOAP在互聯網影響如此大,以至於我們給基於SOAP的解決方案一個特定 的名稱--Web service。SOAP雖然可以支持多種傳輸層協議,不過SOAP最常見的使用方式還是XML+HTTP。SOAP協議的主要接口描述語言(IDL)是 WSDL(Web Service Description Language)。SOAP具有安全、可擴展、跨語言、跨平臺並支持多種傳輸層協議。如果不考慮跨平臺和跨語言的需求,XML的在某些語言裏面具有非常 簡單易用的序列化使用方法,無需IDL文件和第三方編譯器, 例如Java+XStream。

SOAP 是一種採用XML進行序列化和反序列化的協議,它的IDL是WSDL. 而WSDL的描述文件是XSD,而XSD自身是一種XML文件。 這裏產生了一種有趣的在數學上稱之爲“遞歸”的問題,這種現象往往發生在一些具有自我屬性(Self-description)的事物上。

JSON(Javascript Object Notation)

       JSON 起源於弱類型語言Javascript, 它的產生來自於一種稱之爲"Associative array"的概念,其本質是就是採用"Attribute-value"的方式來描述對象。實際上在Javascript和PHP等弱類型語言中,類的 描述方式就是Associative array。JSON的如下優點,使得它快速成爲最廣泛使用的序列化協議之一。

這種Associative array格式非常符合工程師對對象的理解。

 

它保持了XML的人眼可讀(Human-readable)的優點。

 

相對於XML而言,序列化後的數據更加簡潔。 來自於的以下鏈接的研究表明:XML所產生序列化之後文件的大小接近JSON的兩倍。

 

它具備Javascript的先天性支持,所以被廣泛應用於Web browser的應用常景中,是Ajax的事實標準協議。

 

與XML相比,其協議比較簡單,解析速度比較快。

 

鬆散的Associative array使得其具有良好的可擴展性和兼容性。

       Thrift

       Thrift 是Facebook開源提供的一個高性能,輕量級RPC服務框架,其產生正是爲了滿足當前大數據量、分佈式、跨語言、跨平臺數據通訊的需求。 但是,Thrift並不僅僅是序列化協議,而是一個RPC框架。相對於JSON和XML而言,Thrift在空間開銷和解析性能上有了比較大的提升,對於 對性能要求比較高的分佈式系統,它是一個優秀的RPC解決方案;但是由於Thrift的序列化被嵌入到Thrift框架裏面,Thrift框架本身並沒有 透出序列化和反序列化接口,這導致其很難和其他傳輸層協議共同使用(例如HTTP)。

Protobuf

Protobuf具備了優秀的序列化協議的所需的衆多典型特徵。

標準的IDL和IDL編譯器,這使得其對工程師非常友好。

 

序列化數據非常簡潔,緊湊,與XML相比,其序列化之後的數據量約爲1/3到1/10。

 

解析速度非常快,比對應的XML快約20-100倍。

 

提供了非常友好的動態庫,使用非常簡介,反序列化只需要一行代碼。

 

Protobuf 是一個純粹的展示層協議,可以和各種傳輸層協議一起使用;Protobuf的文檔也非常完善。 但是由於Protobuf產生於Google,所以目前其僅僅支持Java、C#### 典型應用場景和非應用場景 Protobuf具有廣泛的用戶基礎,空間開銷小以及高解析性能是其亮點,非常適合於公司內部的對性能要求高的RPC調用。由於Protobuf提供了標 準的IDL以及對應的編譯器,其IDL文件是參與各方的非常強的業務約束,另外,Protobuf與傳輸層無關,採用HTTP具有良好的跨防火牆的訪問屬 性,所以Protobuf也適用於公司間對性能要求比較高的場景。由於其解析性能高,序列化後數據量相對少,非常適合應用層對象的持久化場景。

它的主要問題在於其所支持的語言相對較少,另外由於沒有綁定的標準底層傳輸層協議,在公司間進行傳輸層協議的調試工作相對麻煩。

Avro

Avro 的產生解決了JSON的冗長和沒有IDL的問題,Avro屬於Apache Hadoop的一個子項目。 Avro提供兩種序列化格式:JSON格式或者Binary格式。Binary格式在空間開銷和解析性能方面可以和Protobuf媲美,JSON格式方 便測試階段的調試。 Avro支持的數據類型非常豐富,包括C#### 典型應用場景和非應用場景 Avro解析性能高並且序列化之後的數據非常簡潔,比較適合於高性能的序列化服務。

由於Avro目前非JSON格式的IDL處於實驗階段,而JSON格式的IDL對於習慣於靜態類型語言的工程師來說不直觀。

 

 

選型建議

 以上描述的五種序列化和反序列化協議都各自具有相應的特點,適用於不同的場景。

對於公司間的系統調用,如果性能要求在100ms以上的服務,基於XML的SOAP協議是一個值得考慮的方案。

 

基於Web browser的Ajax,以及Mobile app與服務端之間的通訊,JSON協議是首選。對於性能要求不太高,或者以動態類型語言爲主,或者傳輸數據載荷很小的的運用場景,JSON也是非常不錯的選擇。

 

對於調試環境比較惡劣的場景,採用JSON或XML能夠極大的提高調試效率,降低系統開發成本。

 

當對性能和簡潔性有極高要求的場景,Protobuf,Thrift,Avro之間具有一定的競爭關係。

 

對於T級別的數據的持久化應用場景,Protobuf和Avro是首要選擇。如果持久化後的數據存儲在Hadoop子項目裏,Avro會是更好的選擇。

 

由於Avro的設計理念偏向於動態類型語言,對於動態語言爲主的應用場景,Avro是更好的選擇。

 

對於持久層非Hadoop項目,以靜態類型語言爲主的應用場景,Protobuf會更符合靜態類型語言工程師的開發習慣。

 

如果需要提供一個完整的RPC解決方案,Thrift是一個好的選擇。

 

如果序列化之後需要支持不同的傳輸層協議,或者需要跨防火牆訪問的高性能場景,Protobuf可以優先考慮。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章