跨語言服務部署框架Thrift簡介
Thrift是一個跨語言的服務部署框架,最初由非死book于2007年開發,2008年進入Apache開源項目。Thrift通過一個中 間語言(IDL, 接口定義語言)來定義RPC的接口和數據類型,然后通過一個編譯器生成不同語言的代碼(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),并由生成的代碼負責RPC協議層和傳輸層的實現。
Thrift的系統架構
Thrift包含一個完整的堆棧結構用于構建客戶端和服務器端。下圖描繪了 Thrift 的整體架構。
如圖所示,圖中黃色部分是用戶實現的業務邏輯,褐色部分是根據 Thrift 定義的服務接口描述文件生成的客戶端和服務器端代碼框架,紅色部分是根據 Thrift 文件生成代碼實現數據的讀寫操作。紅色部分以下是 Thrift 的傳輸體系、協議以及底層 I/O 通信,使用 Thrift 可以很方便的定義一個服務并且選擇不同的傳輸協議和傳輸層而不用重新生成代碼。
Thrift實際上是實現了C/S模式,通過代碼生成工具將接口定義文件生成服務器端和客戶端代碼(可以為不同語言),從而實現服務端和客戶端跨語 言的支持。用戶在Thirft描述文件中聲明自己的服務,這些服務經過編譯后會生成相應語言的代碼文件,然后用戶實現服務(客戶端調用服務,服務器端提服 務)便可以了。其中protocol(協議層, 定義數據傳輸格式,可以為二進制或者XML等)和transport(傳輸層,定義數據傳輸方式,可以為TCP/IP傳輸,內存共享或者文件共享等)被用 作運行時庫。
Thrift代碼產生方式
Thrift的網絡棧如下所示:
- Transport層提供了一個簡單的網絡讀寫抽象層。這使得thrift底層的transport從系統其它部分(如:序列化/反序列化)解耦。Transport接口提供的方法:open,close,read,write,flush。
- Protocol抽象層定義了一種將內存中數據結構映射成可傳輸格式的機制。換句話說,Protocol定義了datatype怎樣使用底層的Transport對自己進行編解碼。因此,Protocol的實現要給出編碼機制并負責對數據進行序列化。
- Processor封裝了從輸入數據流中讀數據和向數據數據流中寫數據的操作。讀寫數據流用Protocol對象表示。Processor的結構 體非常簡單:與服務相關的processor實現由編譯器產生。Processor主要工作流程如下:從連接中讀取數據(使用輸入protocol),將 處理授權給handler(由用戶實現),最后將結果寫到連接上(使用輸出protocol)。
- Server將以上所有特性集成在一起:
- 創建一個transport對象
- 為transport對象創建輸入輸出protocol
- 基于輸入輸出protocol創建processor
- 等待連接請求并將之交給processor處理
Thrift支持的數據類型
Thrift 腳本可定義的數據類型包括以下幾種類型:
- Base Types:基本類型
- Struct:結構體類型
- Container:容器類型,即List、Set、Map
- Exception:異常類型
- Service: 定義對象的接口,和一系列方法
Thrift支持的傳輸格式
Thrift可以讓你選擇客戶端與服務端之間傳輸通信協議的類別,在傳輸協議上總體上劃分為文本(text)和二進制(binary)傳輸協議, 為節約帶寬,提供傳輸效率,一般情況下使用二進制類型的傳輸協議為多數,但有時會還是會使用基于文本類型的協議,這需要根據項目/產品中的實際需求:
- TBinaryProtocol – 二進制編碼格式進行數據傳輸。
- TCompactProtocol –高效率的、密集的二進制編碼格式進行數據傳輸,這種協議非常有效的,使用Variable-Length Quantity (VLQ) 編碼對數據進行壓縮。
- TJSONProtocol – 使用JSON的數據編碼協議進行數據傳輸。
- TSimpleJSONProtocol –只提供JSON只寫的協議,適用于通過腳本語言解析
- TDebugProtocol – 在開發的過程中幫助開發人員調試用的,以文本的形式展現方便閱讀。
使用Thrift和其他方式的所產生的內容大小比較結果如下:
在上圖中我們能明顯看出,最臃腫的是RMI,其次是xml,使用Thrift的TCompactProtocol協議和Google 的 Protocol Buffers 相差的不算太多,相比而言還是Google 的 Protocol Buffers效果最佳。
使用Thrift 中的協議和其他方式的所產生的運行開銷比較結果如下:
在上圖中我們能明顯看出,最占資源是REST-XML協議,使用Thrift的TCompactProtocol協議和Google 的 Protocol Buffers 相差的不算太多,相比而言Thrift的TCompactProtocol協議效果最佳。
Thrift支持的傳輸方式
- TSocket- 使用堵塞式I/O進行傳輸,也是最常見的模式。
- TFramedTransport- 使用非阻塞方式,按塊的大小,進行傳輸,類似于Java中的NIO。
- TFileTransport- 顧名思義按照文件的方式進程傳輸,雖然這種方式不提供Java的實現,但是實現起來非常簡單。
- TMemoryTransport- 使用內存I/O,就好比Java中的ByteArrayOutputStream實現。
- TZlibTransport- 使用執行zlib壓縮,不提供Java的實現。
Thrift支持的服務模型
- TSimpleServer – 單線程服務器端使用標準的堵塞式I/O。常用于測試。
- TThreadPoolServer – 多線程服務器端使用標準的堵塞式I/O。
- TNonblockingServer – 多線程服務器端使用非堵塞式I/O,并且實現了Java中的NIO通道。(需使用TFramedTransport數據傳輸方式)
參考資料:
</div> 引用地址:http://www.biaodianfu.com/thrift.html