thrift介绍及应用(一)—介绍
原文:http://blog.csdn.net/guxch/article/details/12157151
------------------------------------------------------------------------------------
一、概述
? ? ? ? Thrift是Apache下的一個(gè)子項(xiàng)目,最早是Facebook的項(xiàng)目,后來Facebook提供給Apache作為開源項(xiàng)目,在官網(wǎng)上,Thrift被描述為“Scalable Cross-Language Services Implementation”,說的通俗一些,Thrift具有以下特征:??????? 與Thrift相類似的開源項(xiàng)目是Google的Protocol Buffer(Protobuf),Protobuf目前提供了 C++、Java、Python 三種語言的 API,比Thrift簡單一些,應(yīng)用也不如Thrift廣泛,有評(píng)論說Protobuf寫復(fù)雜的應(yīng)用比較困難。
?? ? ?? 目前thrift的版本是0.9.1,以下的討論均以該版為基準(zhǔn),代碼語言以C++為基準(zhǔn)。
二、Thrift應(yīng)用場(chǎng)景
??????? Thrift其實(shí)應(yīng)分成三個(gè)部分,一個(gè)叫做Thrift代碼生成器,一個(gè)叫做Thrift應(yīng)用框架(庫),最后一個(gè)是它生成的代碼。Thrift應(yīng)用的基本流程如下圖所示。
從上圖,要生成一個(gè)Thrift應(yīng)用,需用以下文件:
三、Linux下安裝
??????? Thrift的安裝包括上面提到生成代碼生成器和應(yīng)用框架庫,網(wǎng)頁(http://thrift.apache.org/docs/install/)描述了安裝依賴項(xiàng),除了gcc及其編譯工具本身外,編譯Thrift最大的依賴就是boost。安裝過程并不復(fù)雜,請(qǐng)參閱相關(guān)網(wǎng)上文章。
四、Windows下Thrift的使用
??????? 將Windows環(huán)境單獨(dú)拿出來討論是因?yàn)橐郧暗腡hrift版本(0.8以前)是不支持Windows的,雖然有些人做了補(bǔ)丁,但看其文檔,相當(dāng)麻煩。0.8開始支持windows,目前官方文檔的描述中還是需要Cygwin這樣的東西。其實(shí)0.9.1已經(jīng)能很好的支持windows了。
??????? Thrift compiler的編譯:在\compiler\cpp下有一個(gè)compiler.sln的VS2010的解決方案,它有一個(gè)叫做compiler的VC項(xiàng)目。可惜的是,要編譯compiler,必須flex和bison的支持,這個(gè)可以到http://sourceforge.net/projects/winflexbison/?source=dlp下載,在VC的項(xiàng)目屬性中,修改“生成事件->預(yù)先生成事件”中的命令行為(注意win_flex和win_bison的路徑):
[plain]?view plaincopy??????? Thrift庫的編譯:在“\lib\cpp”目錄,有一個(gè)叫thrift.sln的VS2010的解決方案文件,它包含兩個(gè)VC項(xiàng)目:libthriftnb和libthrift,libthrift依賴于boost,libthriftnb依賴于boost和libevent,在正確設(shè)置好引用庫后(先要編譯生成boost和libevent),可以編譯這兩個(gè)工程,得到兩個(gè)dll,即thrift的應(yīng)用框架庫,在thrift應(yīng)用中,需要使用這個(gè)框架庫。
五、Thrift基本概念與應(yīng)用
這一部分很多文章已經(jīng)涉及,本文只是從Thrift的White Paper角度加一些個(gè)人理解與注釋。
1.Thrift有以下幾個(gè)概念:
類型系統(tǒng)(typesystem)
Thrift定義了一套數(shù)據(jù)傳輸描述語言(有點(diǎn)類似IDL),它是“語言中性”的,這個(gè)就是它的類型系統(tǒng)。它分為五種類型(數(shù)據(jù)類型表達(dá)3種,預(yù)定義類/結(jié)構(gòu)1種,接口表達(dá)1種):
基本類型(basictype),也就是bool、byte、i16、i32、i64、double、string,任何語言都有這些基本類型,比較有意思的是string,它即表達(dá)text,也表達(dá)binary bytes。另一個(gè)特點(diǎn)是整型沒有unsigned,原因比較簡單,因?yàn)橛行┱Z言不支持。
- 結(jié)構(gòu)類型(struct):就是C語言中的struct,將基本類型組合起來。
- 容器類型(container):就是集合類型(list/set/map),其中的元素是任何Thrift可識(shí)別的基本、結(jié)構(gòu)、容器類型。【不知道是否有不支持list/set/map的語言,那么Thrift如何處理呢?】
- 異常類型(exception):從數(shù)據(jù)結(jié)構(gòu)講就是結(jié)構(gòu)類型,可以認(rèn)為是便于異常的處理而單獨(dú)拿出來的、預(yù)定義的、有特殊意義的結(jié)構(gòu)類型。
- 服務(wù)定義類型(service):這個(gè)類型實(shí)際是用來定義接口的,Thrift代碼生成器會(huì)根據(jù)這個(gè)定義,生成代碼框架。
傳輸(transport)
也就是信息的傳輸渠道以及讀寫方式,例如,介質(zhì)可以是socket、shared memory或file,Thrift規(guī)定了一些基本的操作(open/close/isOpen/read/write/flush,對(duì)server,再加上listen/accept)。特別的,針對(duì)Socket方式,有TScoket類,對(duì)file方式,有TFileTransport類,上面類比較底層,還有幾個(gè)實(shí)用的類:TBufferedTransport,TFramedTransport,TMemoryBuffer等。
?
協(xié)議(protocol)
是對(duì)傳輸協(xié)議的封裝,也就是傳輸采用二進(jìn)制、XML或者text來表示信息,它的功能有兩個(gè):1.雙向的消息隊(duì)列;2.信息的編碼和解碼(也就是對(duì)上面類型的讀/寫)。關(guān)于流式格式,thrift數(shù)據(jù)類型是自我分割的,意思是說,thrift會(huì)自己在數(shù)據(jù)域的分割處插入標(biāo)志,在解碼的時(shí)候,即使沒有數(shù)據(jù)域定義,thrift也能成功分割出各數(shù)據(jù)域。在若干篇文章中,都提到thrift的二進(jìn)制流式編碼有相當(dāng)?shù)男?#xff08;可以配合壓縮),因此首選的協(xié)議應(yīng)該是binary協(xié)議。
?
版本(versioning)
如果一個(gè)程序分開來開發(fā),那版本問題就是繞不過去的問題。Thrift的版本是通過“field identifiers”來實(shí)現(xiàn)的,每個(gè)結(jié)構(gòu)由其標(biāo)識(shí),結(jié)構(gòu)中的每個(gè)域有其標(biāo)識(shí),這兩個(gè)標(biāo)識(shí)唯一決定了一個(gè)數(shù)據(jù)域。在解碼的時(shí)候,數(shù)據(jù)域的標(biāo)識(shí)被檢查,如果不能識(shí)別,則該數(shù)據(jù)域被拋棄。Thrift也可以通過”Isset”機(jī)制來明確某些域的設(shè)置與否(發(fā)送端用來指明是否設(shè)置,接收端用來檢測(cè)是否設(shè)置)。
四種情況:
?處理器(processor)
就是如何將各部分協(xié)調(diào)起來,形成代碼(或用戶代碼的框架)。它有兩個(gè)重要的類:TProcessor和TServer。TProcessor用來實(shí)現(xiàn)RPC調(diào)用,TServer是所有Server類的基類,TServer類主要處理連接和線程,而不管諸如傳輸、編碼等。用戶代碼主要關(guān)注的一是.thrift文件,二就是這個(gè)接口。Thrift為此實(shí)現(xiàn)了TSimpleServer(單線程), TThreadedServer(每連接一個(gè)線程)和 TThreadPoolServer(線程池)等類。
下圖是thrift生成代碼的基本結(jié)構(gòu)(C++)。
圖中,ServiceIf是根據(jù)接口文件(.thrift)生成的虛接口類,用戶的具體實(shí)現(xiàn)在ServiceHandler中。各種調(diào)用方式在TServer中實(shí)現(xiàn)。【詳細(xì)的描述見實(shí)例】
?
2.Thrift實(shí)現(xiàn)上的幾個(gè)考慮
目標(biāo)語言
雖然有多種選擇,但最常用的(可能也是支持最好的)是C++, Java, and Python。
生成的結(jié)構(gòu)體
數(shù)據(jù)域成員都是公有的,沒有set,get之類的東西,雖然建議采用isset,但也可以不用,系統(tǒng)足夠強(qiáng)健來處理類似“FieldNotSetException”之類的問題,因而也沒有涉及該異常。Read和write方面也是公有的,這樣用戶可以在固有的RPC之外來使用它們。
RPC方法標(biāo)識(shí):實(shí)現(xiàn)RPC時(shí),建立函數(shù)名與函數(shù)指針之間的映射,大致如下(不同的語言表達(dá)方式不同,C++,map):
std::map<std::string,函數(shù)指針> processMap_;
這樣加快函數(shù)調(diào)用。
多線程
對(duì)C++實(shí)現(xiàn),在開發(fā)過程中,thrift開發(fā)人員研究過boost,ACE中與thread,timer相關(guān)的東西,開發(fā)人員不想引入過多的第三方依賴,因此thrift中只有對(duì)boost::shared_ptr的引用是必須的,但為了跨平臺(tái)或獲得更多的功能,一般情況下,boost中thread,timer及其依賴庫也是需要的。
ThreadManager和TimerManager
線程管理類用來管理線程池,定時(shí)器管理類可以定時(shí)觸發(fā)Runnable的對(duì)象,開啟一件事情(可以放到或不放到一個(gè)單獨(dú)線程)。
NonblockingOperation
這個(gè)東西需要libevent的支持。
Compiler(代碼生成器)
這個(gè)東西是用C++寫的,依賴于lex/yacc。代碼生成分兩步:第一,檢查包含的文件和類型定義文件,生成“解析樹”(the parse tree);第二,將各類型放到解析樹中,根據(jù)解析樹生成代碼。
TFileTransport
這個(gè)類(及其繼承類)可以將request消息記入文件,為提高性能,它先緩存記錄,并存入磁盤。記錄文件是分塊的(文件固定大小),采用padding,記錄不能跨塊。
(未完)
總結(jié)
以上是生活随笔為你收集整理的thrift介绍及应用(一)—介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hive的系统架构
- 下一篇: python包管理机制_Go 1.5之前