Thrift簡析


Thrift源於大名鼎鼎的facebook之手,在2007年facebook提交Apache基金會將Thrift作為一個開源項目,對於當時的facebook來說創造thrift是為了解決facebook系統中各系統間大數據量的傳輸通信以及系統之間語言環境不同需要跨平台的特性。所以thrift可以支持多種程序語言,例如: C++, C#, Cocoa, Erlang, Haskell, Java, Ocami, Perl, PHP, Python, Ruby, Smalltalk. 在多種不同的語言之間通信thrift可以作為二進制的高性能的通訊中間件,支持數據(對象)序列化和多種類型的RPC服務。Thrift適用於程序對程 序靜態的數據交換,需要先確定好他的數據結構,他是完全靜態化的,當數據結構發生變化時,必須重新編輯IDL文件,代碼生成,再編譯載入的流程,跟其他IDL工具相比較可以視為是Thrift的弱項,Thrift適用於搭建大型數據交換及存儲的通用工具,對於大型系統中的內部數據傳輸相對於JSON和xml無論在性能、傳輸大小上有明顯的優勢。

Thrift 主要由5個部分組成:

  • 類型系統以及 IDL 編譯器:負責由用戶給定的 IDL 文件生成相應語言的接口代碼
  • TProtocol:實現 RPC 的協議層,可以選擇多種不同的對象串行化方式,如 JSON, Binary。
  • TTransport:實現 RPC 的傳輸層,同樣可以選擇不同的傳輸層實現,如socket, 非阻塞的 socket, MemoryBuffer 等。
  • TProcessor:作為協議層和用戶提供的服務實現之間的紐帶,負責調用服務實現的接口。
  • TServer:聚合 TProtocol, TTransport 和 TProcessor 幾個對象。

上述的這5個部件都是在 Thrift 的源代碼中通過為不同語言提供庫來實現的,這些庫的代碼在 Thrift 源碼目錄的 lib 目錄下面,在使用 Thrift 之前需要先熟悉與自己的語言對應的庫提供的接口。

首先思考一下分布式系統中的 RPC (Remote Procedure Call) 問題,一個完整的 RPC 模塊需要可以分為三個層次

  • 服務層(service):RPC 接口定義與實現
  • 協議層(protocol):RPC 報文格式和數據編碼格式
  • 傳輸層(transport):實現底層的通信(如 socket)以及系統相關的功能(如事件循環、多線程)

在實際的大型分布式系統中,不同的服務往往會使用不同的語言來實現,所以一般的 RPC 系統會提供一種跨語言的過程調用功能,比如一段用C++實現的客戶端代碼可以遠程調用一個用 C# 實現的服務。實現跨語言 RPC 有兩種方法:

  • 靜態代碼生成:開發者用一種中間語言(IDL,接口定義語言)來定義 RPC 的接口和數據類型,然后通過一個編譯器來生成不同語言的代碼(如C++, Java, Python),並由生成的代碼來負責 RPC 協議層和傳輸層的實現。例如,服務的實現用C++,則服務端需要生成實現RPC協議和傳輸層的C++代碼,服務層使用生成的代碼來實現與客戶端的通信;而如果客戶端用 Python,則客戶端需要生成Python代碼。
  • 基於“自省”的動態類型系統來實現:協議和傳輸層可以只用一種語言實現成一個庫,但是這種語言需要關聯一個具備“自省”或者反射機制的動態類型系統,對外提供其他語言的綁定,客戶端和服務端通過語言綁定來使用 RPC。比如,可以考慮用 C 和 GObject 實現一個 RPC 庫,然后通過 GObject 實現其他語言的綁定。

第一種方法的優點是RPC的協議層和傳輸層的實現不需要和某種動態類型系統(如GObject)綁定在一起,同時避免了動態類型檢查和轉換,程序效率比較高,但是它的缺點是要為不同語言提供不同的 RPC 協議層和傳輸層實現。第二種方法的主要難度在於語言綁定和通用的對象串行化機制的實現,同時也需要考慮效率的問題。

Thrift 是一個基於靜態代碼生成的跨語言的RPC協議棧實現,它可以生成包括C++, Java, Python, Ruby, PHP 等主流語言的代碼,這些代碼實現了 RPC 的協議層和傳輸層功能,從而讓用戶可以集中精力於服務的調用和實現。Cassandra 的服務訪問協議是基於 Thrift 來實現的。

相關文章


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM