Thrift
Thrift是一種接口描述語言和二進制通訊協議,[1]它被用來定義和創建跨語言的服務。[2]它被當作一個遠程過程調用(RPC)框架來使用,是由Facebook為「大規模跨語言服務開發」而開發的。它通過一個代碼生成引擎聯合了一個軟件棧,來創建不同程度的、無縫的跨平台高效服務,可以使用C#、C++(基於POSIX兼容系統[3])、Cappuccino、[4]Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。[5]雖然它以前是由Facebook開發的,但它現在是Apache軟件基金會的開源項目了。該實現被描述在2007年4月的一篇由Facebook發表的技術論文中,該論文現由Apache掌管。[6]
開發者 | Apache軟件基金會 |
---|---|
當前版本 | 0.9.3(2015年10月6日 | )
原始碼庫 | |
類型 | 遠程過程調用框架 |
許可協議 | Apache許可證 2.0 |
網站 | thrift |
架構
Thrift包含一套完整的棧來創建客戶端和服務端程序。[7]頂層部分是由Thrift定義生成的代碼。而服務則由這個文件客戶端和處理器代碼生成。在生成的代碼里會創建不同於內建類型的數據結構,並將其作為結果發送。協議和傳輸層是運行時庫的一部分。有了Thrift,就可以定義一個服務或改變通訊和傳輸協議,而無需重新編譯代碼。除了客戶端部分之外,Thrift還包括伺服器基礎設施來集成協議和傳輸,如阻塞、非阻塞及多線程伺服器。棧中作為I/O基礎的部分對於不同的語言則有不同的實現。
Thrift支持眾多通訊協議:[7]
- TBinaryProtocol – 一種簡單的二進制格式,簡單,但沒有為空間效率而優化。比文本協議處理起來更快,但更難於調試。
- TCompactProtocol – 更緊湊的二進制格式,處理起來通常同樣高效。
- TDebugProtocol – 一種人類可讀的文本格式,用來協助調試。
- TDenseProtocol – 與TCompactProtocol類似,將傳輸數據的元信息剝離。
- TJSONProtocol – 使用JSON對數據編碼。
- TSimpleJSONProtocol – 一種只寫協議,它不能被Thrift解析,因為它使用JSON時丟棄了元數據。適合用腳本語言來解析。[8]
支持的傳輸協議有:
- TFileTransport – 該傳輸協議會寫文件。
- TFramedTransport – 當使用一個非阻塞伺服器時,要求使用這個傳輸協議。它按幀來發送數據,其中每一幀的開頭是長度信息。
- TMemoryTransport – 使用存儲器映射輸入輸出。(Java的實現使用了一個簡單的
ByteArrayOutputStream
。) - TSocket – 使用阻塞的套接字I/O來傳輸。
- TZlibTransport – 用zlib執行壓縮。用於連接另一個傳輸協議。
Thrift還提供眾多的伺服器,包括:
- TNonblockingServer – 一個多線程伺服器,它使用非阻塞I/O(Java的實現使用了NIO通道)。TFramedTransport必須跟這個伺服器配套使用。
- TSimpleServer – 一個單線程伺服器,它使用標準的阻塞I/O。測試時很有用。
- TThreadPoolServer – 一個多線程伺服器,它使用標準的阻塞I/O。
優點
Thrift一些已經明確的優點包括:[來源請求]
- 跟一些替代選擇,比如SOAP相比,跨語言序列化的代價更低,因為它使用二進制格式。
- 它有一個又瘦又乾淨的庫,沒有編碼框架,沒有XML配置文件。
- 綁定感覺很自然。例如,Java使用
java.util.ArrayList<String>
;C++使用std::vector<std::string>
。 - 應用層通訊格式與序列化層通訊格式是完全分離的。它們都可以獨立修改。
- 預定義的序列化格式包括:二進制格式、對HTTP友好的格式,以及緊湊的二進制格式。
- 兼作跨語言文件序列化。
- 協議使用軟版本號機制軟件版本管理[需要解釋]。Thrift不要求一個中心化的和顯式的版本號機制,例如主版本號/次版本號。鬆耦合的團隊可以輕鬆地控制RPC調用的演進。
- 沒有構建依賴也不含非標準化的軟件。不存在不兼容的軟件許可證混用的情況。
創建一個Thrift服務
Thrift由C++編寫,但可以為眾多語言創建代碼。要創建一個Thrift服務,必須寫一些Thrift文件來描述它,為目標語言生成代碼,並且寫一些代碼來啟動伺服器及從客戶端調用它。下面就是一個這樣的描述文件的代碼示例:
enum PhoneType {
HOME,
WORK,
MOBILE,
OTHER
}
struct Phone {
1: i32 id,
2: string number,
3: PhoneType type
}
Thrift將由這個描述信息生成獨立的代碼。例如,在Java里,PhoneType
將是Phone
類中一個簡單的enum
。
參見
- 數據序列化格式比較
- Apache Avro
- ASN.1(抽象語法標記一)
- Caucho的Hessian
- Google的Protocol Buffers
- 外部數據表示法
- ZeroC的ICE
- SDXF(結構化數據交換格式)
參考文獻
- ^ 安装和使用Java下的Apache Cassandra第4部分(Thrift客户端). http://www.sodeso.nl/: Sodeso–軟件開發解決方案. [2011-03-30]. (原始內容存檔於2010-08-15).
Thrift是一個獨立的Apache項目,簡單地說,就是一種二進制通訊協議。
(英文) - ^ Andrew Prunicki. Apache Thrift:介绍. http://www.ociweb.com/: 對象計算有限公司–一家開放解決方案公司. [2011-04-11]. (原始內容存檔於2011-07-23).
通過一種簡單且直截了當的接口定義語言(IDL),Thrift允許你定義和創建一種服務,這種服務既可以用多種語言來實現,又可以由多種語言來使用。利用代碼生成功能,Thrift可以創建一套文件,然後通過這套文件來創建服務端和客戶端程序。除了互操作性之外,Thrift還非常高效,這得益於一套獨特的、在時間和空間上都高效的序列化機制。
(英文) - ^ Thrift的要求 (頁面存檔備份,存於互聯網檔案館),要支持Windows參見這裏 (頁面存檔備份,存於互聯網檔案館)(英文)
- ^ Fred Potter,使用Thrift + Cappuccino (頁面存檔備份,存於互聯網檔案館),parallel48的甜美的郵件博客,2010年6月10日。(英文)
- ^ Andrew Prunicki. Apache Thrift:代码生成. http://www.ociweb.com/: 對象計算有限公司–一家開放解決方案公司. [2011-04-12]. (原始內容存檔於2011-07-23).
Thrift在不同程度上支持許多語言,完整的名單如下:(請小心,不能僅僅因為你的語言在某種程度上被支持,就假設它支持所有的Thrift特性。比如Python,僅支持TBinaryProtocol。)Cocoa、C++、C#、Erlang、Haskell、Java、OCaml、Perl、PHP、Python、Ruby和Smalltalk。
(英文) - ^ Mark Slee、Aditya Agarwal、Marc Kwiatkowski,Thrift:大規模跨語言服務的實現 (頁面存檔備份,存於互聯網檔案館)(英文)
- ^ 7.0 7.1 Andrew Prunicki. Apache Thrift:介绍. http://www.ociweb.com/: 對象計算有限公司–一家開放解決方案公司. [2011-04-11]. (原始內容存檔於2011-07-23).
該棧的頂層部分是從你的Thrift定義文件生成的代碼。Thrift服務在生成的客戶端和處理器代碼中提供結果。在圖中,這些是用棕色框表示的。被發送的數據結構(不同於內建類型)也由生成的代碼產生。這些結果由紅色框表示。通訊和傳輸協議是Thrift運行時庫的一部分。因此,用Thrift,你可以定義一個服務,並可以自由地改變通訊和傳輸協議,而無需重新生成你的代碼。Thrift還包括一個伺服器基礎設施,以集成各個通訊和傳輸協議。它支持阻塞、非阻塞、單線程以及多線程伺服器。棧中「作為I/O基礎」的部分則是因語言而異的。對於Java和Python網絡I/O,Thrift庫對其內建庫起到了槓桿作用,而C++的實現使用了它自己的習慣。
(英文) - ^ Skelton, Steven. 对开发者友好的Thrift请求日志. [2014年7月3日]. (原始內容存檔於2014年7月14日).(英文)
外部連結
- 官方網站(英文)
- Thrift:缺失的指南(頁面存檔備份,存於互聯網檔案館)(英文)
- Thrift螞蟻任務(頁面存檔備份,存於互聯網檔案館)(英文)
- Thrift指導(頁面存檔備份,存於互聯網檔案館)(英文)