簡介
Thrift是一種接口描述語言和二進(jìn)制通訊協(xié)議膏燃,它被用來定義和創(chuàng)建跨語言的服務(wù)科雳。它被當(dāng)作一個遠(yuǎn)程過程調(diào)用(RPC)框架來使用秃踩,是由Facebook為“大規(guī)闹钥欤跨語言服務(wù)開發(fā)”而開發(fā)的。
它通過一個代碼生成引擎聯(lián)合了一個軟件棧搔啊,來創(chuàng)建不同程度的柬祠、無縫的跨平臺高效服務(wù),可以使用C#负芋、C++(基于POSIX兼容系統(tǒng))漫蛔、Cappuccino、Cocoa旧蛾、Delphi莽龟、Erlang、Go锨天、Haskell毯盈、Java、Node.js病袄、OCaml搂赋、Perl、PHP益缠、Python脑奠、Ruby和Smalltalk。
另外幅慌,Thrift早期由Facebook開發(fā)宋欺,目前已成為Apache軟件基金會的開源項(xiàng)目。
基本架構(gòu)
類似于計算機(jī)網(wǎng)絡(luò)胰伍,Thrift包含一套完整的棧來創(chuàng)建客戶端和服務(wù)端程序齿诞。
- 頂層部分是由Thrift定義生成的代碼。而服務(wù)則由這個文件客戶端和處理器代碼生成喇辽。在生成的代碼里會創(chuàng)建不同于內(nèi)建類型的數(shù)據(jù)結(jié)構(gòu)掌挚,并將其作為結(jié)果發(fā)送雨席。
- 協(xié)議層和傳輸層是運(yùn)行時庫的一部分菩咨。有了Thrift,就可以定義一個服務(wù)或改變通訊和傳輸協(xié)議陡厘,而無需重新編譯代碼抽米。除了客戶端部分之外,Thrift還包括服務(wù)器基礎(chǔ)設(shè)施來集成協(xié)議和傳輸糙置,如阻塞云茸、非阻塞及多線程服務(wù)器。
- IO層在棧中作為基礎(chǔ)部分對于不同的語言則有不同的實(shí)現(xiàn)谤饭。
使用
快送入門
根據(jù)官網(wǎng)标捺,使用Thrift前需要下載Thrift并且構(gòu)建和安裝Thrift編譯器懊纳。
在使用Thrift進(jìn)行編程時,需要以下幾步(詳細(xì)過程可見Apache Thrift Tutorial):
- 創(chuàng)建
.thrift
文件 - 使用Thrift編譯器編譯為特定語言的源碼
- 根據(jù)源碼實(shí)現(xiàn)服務(wù)的功能
其實(shí)亡容,如果你是一個Java開發(fā)者嗤疯,使用Thrfit有一個更好的方式:借助Swift(并不是指蘋果的Swift語言)。使用Swift闺兢,你可以告別書寫thrift文件并且進(jìn)行多余的一步編譯茂缚,而且也不用忍受由thrift生成的冗長的Java文件,一切都可以用Java代碼和注解搞定??
樣例代碼thrift_demo已提交碼云
Thrift IDL
IDL即為Interface Description Language屋谭,對于Thrift有其特定的語法脚囊。詳細(xì)內(nèi)容可以參考:Thrift interface description language
PS:若采用Jetbrains出品的IDE,可以安裝Thrift Support插件來對Thrift語法做出支持桐磁。
原有數(shù)據(jù)類型
基本類型
- 布爾型:bool
- 整型:byte悔耘、i16、i32我擂、i64
- 浮點(diǎn)型:double
- 字符串:string(utf8編碼)
容器類型
- 有序可重復(fù):list<t>(對應(yīng)Java的ArrayList)
- 無序不可重復(fù):set<t>(對應(yīng)Java的HashSet)
- 關(guān)聯(lián)容器:map<k,v>(對應(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
}
說明:
- 字段可以采用
=
來設(shè)置默認(rèn)值扶踊。 - 數(shù)字標(biāo)簽不要輕易修改泄鹏。在修改時可以考慮新加一個數(shù)字標(biāo)簽,丟棄原有的字段秧耗。
- 字段前標(biāo)識
required
表示备籽,該字段必填,自然傳輸時必然會序列化分井;字段前無標(biāo)識车猬,表示可以不填充,但一定會序列化尺锚;字段前標(biāo)識optional
表示該字段珠闰,可以不填充,并且不填充也不會序列化瘫辩。
異常類型
異常類型的定義和結(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);
}
說明:
- 所有的參數(shù)都是
const
類型,不能作為返回值 -
oneway
關(guān)鍵字用來表示client發(fā)出請求后不必等待回復(fù)(非阻塞)直接進(jìn)行下面的操作卷扮。所以其返回值一定為void
荡澎。 - 繼承類必須實(shí)現(xiàn)這些方法均践。
- 服務(wù)支持繼承,一個service可使用
extends
關(guān)鍵字繼承另一個service摩幔。 - 服務(wù)中的函數(shù)不支持重載浊猾。
文件間關(guān)系
定義本文件的所處的命名空間可以采用namespace
關(guān)鍵字,其效果同Java中的包热鞍。使用命名空間后需指定語言類型葫慎,如java。示例如下:
namespace java demo.thrift
使用其他文件的內(nèi)容需要使用include
后接其他文件名薇宠,其他文件名需要用單引號修飾偷办。示例如下:
include 'PersonDomain.thrift'
其他
- Thrift支持C多行風(fēng)格和Java/C++單行風(fēng)格。
-
typedef
用于定義數(shù)據(jù)結(jié)構(gòu)別名
傳輸體系
傳輸體系由傳輸協(xié)議和傳輸方式構(gòu)成澄港,具體內(nèi)容在和 Thrift 的一場美麗邂逅一文中有更為詳細(xì)的說明椒涯,這里就是粗略枚舉一些。
傳輸協(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:常常用以編碼人員測試湖苞,以文本的形式展現(xiàn)方便閱讀
- ...
傳輸方式
- TFileTransport:該傳輸協(xié)議會寫文件。
- TFramedTransport:當(dāng)使用一個非阻塞服務(wù)器時详囤,要求使用這個傳輸協(xié)議财骨。它按幀來發(fā)送數(shù)據(jù),其中每一幀的開頭是長度信息藏姐。
- TMemoryTransport:使用存儲器映射輸入輸出隆箩。(Java的實(shí)現(xiàn)使用了一個簡單的
ByteArrayOutputStream
。) - TSocket:使用阻塞的套接字I/O來傳輸羔杨。
- TZlibTransport:用zlib執(zhí)行壓縮捌臊。用于連接另一個傳輸協(xié)議。
- ...
服務(wù)器
Thrift自帶了一些好用的服務(wù)器程序兜材,以Java為例理澎,大致有下面這些:
- TNonblockingServer:一個多線程服務(wù)器,它使用非阻塞I/O(Java的實(shí)現(xiàn)使用了NIO通道)护姆。TFramedTransport必須跟這個服務(wù)器配套使用矾端。
- TSimpleServer:一個單線程服務(wù)器,它使用標(biāo)準(zhǔn)的阻塞I/O卵皂。測試時很有用。
- TThreadPoolServer:一個多線程服務(wù)器砚亭,它使用標(biāo)準(zhǔn)的阻塞I/O灯变。
- ...