簡(jiǎn)介
Thrift是一種接口描述語(yǔ)言和二進(jìn)制通訊協(xié)議,它被用來(lái)定義和創(chuàng)建跨語(yǔ)言的服務(wù)。它被當(dāng)作一個(gè)遠(yuǎn)程過(guò)程調(diào)用(RPC)框架來(lái)使用,是由Facebook為“大規(guī)模跨語(yǔ)言服務(wù)開(kāi)發(fā)”而開(kāi)發(fā)的。
它通過(guò)一個(gè)代碼生成引擎聯(lián)合了一個(gè)軟件棧,來(lái)創(chuàng)建不同程度的、無(wú)縫的跨平臺(tái)高效服務(wù),可以使用C#、C++(基于POSIX兼容系統(tǒng))、Cappuccino、Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。
另外,Thrift早期由Facebook開(kāi)發(fā),目前已成為Apache軟件基金會(huì)的開(kāi)源項(xiàng)目。
基本架構(gòu)
類似于計(jì)算機(jī)網(wǎng)絡(luò),Thrift包含一套完整的棧來(lái)創(chuàng)建客戶端和服務(wù)端程序。
- 頂層部分是由Thrift定義生成的代碼。而服務(wù)則由這個(gè)文件客戶端和處理器代碼生成。在生成的代碼里會(huì)創(chuàng)建不同于內(nèi)建類型的數(shù)據(jù)結(jié)構(gòu),并將其作為結(jié)果發(fā)送。
- 協(xié)議層和傳輸層是運(yùn)行時(shí)庫(kù)的一部分。有了Thrift,就可以定義一個(gè)服務(wù)或改變通訊和傳輸協(xié)議,而無(wú)需重新編譯代碼。除了客戶端部分之外,Thrift還包括服務(wù)器基礎(chǔ)設(shè)施來(lái)集成協(xié)議和傳輸,如阻塞、非阻塞及多線程服務(wù)器。
- IO層在棧中作為基礎(chǔ)部分對(duì)于不同的語(yǔ)言則有不同的實(shí)現(xiàn)。

使用
快送入門
根據(jù)官網(wǎng),使用Thrift前需要下載Thrift并且構(gòu)建和安裝Thrift編譯器。
在使用Thrift進(jìn)行編程時(shí),需要以下幾步(詳細(xì)過(guò)程可見(jiàn)Apache Thrift Tutorial):
- 創(chuàng)建
.thrift文件 - 使用Thrift編譯器編譯為特定語(yǔ)言的源碼
- 根據(jù)源碼實(shí)現(xiàn)服務(wù)的功能
其實(shí),如果你是一個(gè)Java開(kāi)發(fā)者,使用Thrfit有一個(gè)更好的方式:借助Swift(并不是指蘋果的Swift語(yǔ)言)。使用Swift,你可以告別書寫thrift文件并且進(jìn)行多余的一步編譯,而且也不用忍受由thrift生成的冗長(zhǎng)的Java文件,一切都可以用Java代碼和注解搞定??
樣例代碼thrift_demo已提交碼云
Thrift IDL
IDL即為Interface Description Language,對(duì)于Thrift有其特定的語(yǔ)法。詳細(xì)內(nèi)容可以參考:Thrift interface description language
PS:若采用Jetbrains出品的IDE,可以安裝Thrift Support插件來(lái)對(duì)Thrift語(yǔ)法做出支持。
原有數(shù)據(jù)類型
基本類型
- 布爾型:bool
- 整型:byte、i16、i32、i64
- 浮點(diǎn)型:double
- 字符串:string(utf8編碼)
容器類型
- 有序可重復(fù):list<t>(對(duì)應(yīng)Java的ArrayList)
- 無(wú)序不可重復(fù):set<t>(對(duì)應(yīng)Java的HashSet)
- 關(guān)聯(lián)容器:map<k,v>(對(duì)應(yīng)Java的HashMap)
可定制數(shù)據(jù)類型
結(jié)構(gòu)體類型
由struct關(guān)鍵字定義,需要給字段提供數(shù)字標(biāo)簽,示例如下:
struct PersonVo{
1:required i32 id,
2:required string name,
3:required double wealth
}
說(shuō)明:
- 字段可以采用
=來(lái)設(shè)置默認(rèn)值。 - 數(shù)字標(biāo)簽不要輕易修改。在修改時(shí)可以考慮新加一個(gè)數(shù)字標(biāo)簽,丟棄原有的字段。
- 字段前標(biāo)識(shí)
required表示,該字段必填,自然傳輸時(shí)必然會(huì)序列化;字段前無(wú)標(biāo)識(shí),表示可以不填充,但一定會(huì)序列化;字段前標(biāo)識(shí)optional表示該字段,可以不填充,并且不填充也不會(huì)序列化。
異常類型
異常類型的定義和結(jié)構(gòu)體基本相同,但采用exception作為關(guān)鍵字。
枚舉類型
采用enum作為關(guān)鍵字定義,示例如下:
enum ColorEnum{
WHITE = 0;
BLACK = 1;
BLUE = 2;
}
常量類型
采用const關(guān)鍵字定義,示例如下:
const i32 INT_CONST = 1234;
服務(wù)類型
使用service關(guān)鍵字定義,用于描述接口,類似于Java中的接口文件。示例如下:
service PersonService {
PersonDomain.PersonVo get(1:i32 id);
oneway void add(1:PersonDomain.PersonVo pv);
}
說(shuō)明:
- 所有的參數(shù)都是
const類型,不能作為返回值 -
oneway關(guān)鍵字用來(lái)表示client發(fā)出請(qǐng)求后不必等待回復(fù)(非阻塞)直接進(jìn)行下面的操作。所以其返回值一定為void。 - 繼承類必須實(shí)現(xiàn)這些方法。
- 服務(wù)支持繼承,一個(gè)service可使用
extends關(guān)鍵字繼承另一個(gè)service。 - 服務(wù)中的函數(shù)不支持重載。
文件間關(guān)系
定義本文件的所處的命名空間可以采用namespace關(guān)鍵字,其效果同Java中的包。使用命名空間后需指定語(yǔ)言類型,如java。示例如下:
namespace java demo.thrift
使用其他文件的內(nèi)容需要使用include后接其他文件名,其他文件名需要用單引號(hào)修飾。示例如下:
include 'PersonDomain.thrift'
其他
- Thrift支持C多行風(fēng)格和Java/C++單行風(fēng)格。
-
typedef用于定義數(shù)據(jù)結(jié)構(gòu)別名
傳輸體系
傳輸體系由傳輸協(xié)議和傳輸方式構(gòu)成,具體內(nèi)容在和 Thrift 的一場(chǎng)美麗邂逅一文中有更為詳細(xì)的說(shuō)明,這里就是粗略枚舉一些。
傳輸協(xié)議
- TBinaryProtocol:是Thrift的默認(rèn)協(xié)議,使用二進(jìn)制編碼格式進(jìn)行數(shù)據(jù)傳輸,基本上直接發(fā)送原始數(shù)據(jù)
- TCompactProtocol:壓縮的、密集的數(shù)據(jù)傳輸協(xié)議,基于Variable-length quantity的zigzag 編碼格式
- TJSONProtocol:以JSON (JavaScript Object Notation)數(shù)據(jù)編碼協(xié)議進(jìn)行數(shù)據(jù)傳輸
- TDebugProtocol:常常用以編碼人員測(cè)試,以文本的形式展現(xiàn)方便閱讀
- ...
傳輸方式
- TFileTransport:該傳輸協(xié)議會(huì)寫文件。
- TFramedTransport:當(dāng)使用一個(gè)非阻塞服務(wù)器時(shí),要求使用這個(gè)傳輸協(xié)議。它按幀來(lái)發(fā)送數(shù)據(jù),其中每一幀的開(kāi)頭是長(zhǎng)度信息。
- TMemoryTransport:使用存儲(chǔ)器映射輸入輸出。(Java的實(shí)現(xiàn)使用了一個(gè)簡(jiǎn)單的
ByteArrayOutputStream。) - TSocket:使用阻塞的套接字I/O來(lái)傳輸。
- TZlibTransport:用zlib執(zhí)行壓縮。用于連接另一個(gè)傳輸協(xié)議。
- ...
服務(wù)器
Thrift自帶了一些好用的服務(wù)器程序,以Java為例,大致有下面這些:
- TNonblockingServer:一個(gè)多線程服務(wù)器,它使用非阻塞I/O(Java的實(shí)現(xiàn)使用了NIO通道)。TFramedTransport必須跟這個(gè)服務(wù)器配套使用。
- TSimpleServer:一個(gè)單線程服務(wù)器,它使用標(biāo)準(zhǔn)的阻塞I/O。測(cè)試時(shí)很有用。
- TThreadPoolServer:一個(gè)多線程服務(wù)器,它使用標(biāo)準(zhǔn)的阻塞I/O。
- ...