[Thrift分析]
Thrift定義一套IDL(Interface Definition Language)用於描述接口,通常后綴名為.thrift,通過thrift程序把.thrift文件導出成各種不一樣的代碼的協議定義。除此之外,Thrift自定了一套C/S交互的框架,幫助開發者免去人工解包/打包協議的工作。下面會按文件從里到外仔仔細細地分析Thrift整個框架體系。
Thrift定義的數據沒有構造函數,導致有些情況下不方便。無法定義list成員變量,有些情況下也很不方便。C++ coder的硬傷。
[Common]
公共文件放置於根目錄下,下面一一介紹。
1、config.h:此文件是thrift的configure腳本檢測出的你的操作系統環境頭文件。此文件為configure腳本生成。是一堆宏命令,例如可能有個宏,如果有某個頭文件則定義為1,否則為0,以此來提供代碼中感知開發者操作系統環境的能力。
2、Thrift.h、Thrift.cpp:此文件提供2個類,TOutput、TException。TOutput用於輸出,默認輸出到stderr,提供了print,(),perror()三個函數用於輸出,有一個全局變量GlobalOutput,其它地方的輸出都通過此變量控制。TException繼承於std::exception,提供what方法。
3、TProcessor.h:此文件為特定功能類,只因此類功能只有1個文件,所以放在在根目錄下。此類提供process函數接口,一個虛函數是用於開發者繼承,另一個提供一個入口。構造函數為protected,所以顯示不能生成此類的的實例,只能生成此類子類的實例。Auto-Gen的processor會把調用dispatch到相應的service接口。
4、TLogging.h:此文件提供各種log宏,大至分3類,debug、log、erro,但是與TOutput無關。
5、TApplicationException.h/.cpp:此文件類為繼承於TException。提供了type字段,type用於分類錯誤類型。此類提供了對protocol的write和read的支持,即提供了RPC能力。
6、TReflectionLocal.h:暫未知,后續補充。
【protocol】
1、TProtocol.h:定義到協議類TProtocol和TProtocolFactory基類,這2個類本身無作用,是個基類,提供操作協議的統一接口。
2、TProtocolException.h:和TApplicationException類似,繼承於TException。提供了TProtocolExceptionType字段,以分類protocol錯誤類型。
3、TOneWayProtocol.h:內含TWriteOnlyProtocol、TReadOnlyProtocol,均繼承於TProtocol。TWriteOnlyProtocl把所有的read方法都拋出異常,TReadOnlyProtocl同理。
4、TProtocolTap.h:內含TProtocolTap類,此類實現監聽功能,即若B對象需要監聽A對象,則生成TProtocolTap對象,以A、B為參數,以后要讀A的時候,通過TProtocolTap對象讀取,TProtocolTap會把讀取請求傳遞給A,拿到結果后把結果寫入到B。即完成B對A的監聽。
5、TBase64Utils.h/.cpp:內含base64方法。
6、TBinaryProtocol.h/.cpp:把數據類型的內存二進制直接寫入到transport里面。
7、TJSONProtocol.h/.cpp:把數據以JSON的形式寫入到transport,例如一個字符串會加上""。
8、TCompactProtocol.h/.cpp:把根據thrift-110,實現數據的緊縮協議。
9、TDebugProtocol、TDenseProtocol:thrift0.5版本中這2個類正在實驗中,推薦不用。
So,開發者直接使用的高頻protol內容為:TBinaryProtocol、TJSONProtocol、TProtocolTap、TBase64Utils。
【transport】
1、TTransport.h:Transport基類,提供的接口大致可按如下分類:open/close、read/write、peek。transport的目的只有2個,一個是read指定長度數據,一個是write指定長度數據。
2、TServerTransport.h:服務端transport基類,主要是為監聽的socket提供功能(Client總不需要listen、accept吧)。接口分類:listen()、accept()、interrupt()。
3、TShortReadTransport.h:測試用,對讀取采用隨機長度讀取,開發者不應該使用。
4、TSocket.h/.cpp:客戶端的socket transport實現。通過指定host、port,通過TTransport中的方法即可實現數據的發送。
5、TSocketPool.h/.cpp:繼承於TSocket,此類提供管理多個server的能力,server的host&port聚合為TSocketPoolServer對象,存儲在TSocketPool中。
6、TTransportException.h/.cpp:與TProtocolException類似,提供transport的錯誤類型。
7、TServerSocket.h/.cpp:實現了TServerTransport,accept后會返回一個TSocket。常用方法為listen()、accept()、interrupt()。
8、TBufferTransports.h/.cpp:
1)TBufferBase類提供對buffer的抽象操作,四個指針:rBase_、rBound_、wBase_、wBound_。
2)TUnderlyingTransport提供buffer的生成,四個變量:rBuf_、rBufSize_、wBuf_、wBufSize_,以及集成了一個trans_。
3)TBufferedTransport完成從transport讀取數據到buf的操作,buffer長度固定。
4)TBufferedTransportFactory工廠類。
5)TFramedTransport,與TBufferedTransport相比,buf會變,不調用flush的數據就不會發到transport。
6)TFramedTransportFactory工廠類。
7)TMemoryBuffer類繼承於TBufferBase,數據存儲在內存,沒有也不會通過trans_發送。
黑體加粗部分為對開發者暴露類。
9、TFDTransport.h/.cpp:直接從文件中read/write,FD就是file description的縮寫。
10、TSimpleFileTransport.h/.cpp:繼承於TFDTransport,添加根據文件名打開FD的功能。
11、……
【processor】
1、StatsProcessor.h:用於輸出RPC調用LOG,此類用於調試。
2、PeekProcessor.h/.cpp:
【concurrency】
1、Thread.h:提供Runnable,用於開發者實現一個可供Thread調用的任務。Thread綁定一個Runnable,通過start方法開啟線程調用Runnable。ThreadFactory根據Runnable產生Thread。
2、Monitor.h:提供條件變量功能。
3、Exception.h:提供一些繼承於TException的子類,用於標記異常。
4、Mutex.h/.cpp:提供一般鎖/讀寫鎖,以及相應的Guard。
5、ThreadManager.h/.cpp:工作線程(Worker)和任務管理器(Task)。類似於Cocoa中的GCD,可設置N個執行線程,M個Task。另外還有許多可配置項。
6、PosixThreadFactory.h/.cpp:一個線程工廠。
7、Util.h/.cpp:提供些有用的輔助方法。
8、FunctionRunner.h:提供把函數包裝成Runnable的功能。
9、TimerManager.h/.cpp:類似於ThreadManager。Dispatcher為唯一的工作線程,當有task時,從task_list中取出到時間的task以執行。單線程。
【server】
1、TServer.h:
1)TEventHanlder是服務端實現功能的地方,實現preServe,clientBegin,clientEnd方法。preServe()在listen成功后只調用一次。每接受一個新Client,clientBegin和clientEnd就調用一次。
2)TServer是一個虛基類,綁定一個TProcessor,用於處理數據,個TServerTransport用於處理數據發送與連接,一個eventHanlder用於將數據dispatch到服務端自己的邏輯代碼中。提供serve()=0方法,是開啟服務的入口。此類只是一個基類。實現了Runnable接口,可以被線程TThread喚起。
2、TSimpleServer.h:是TServer的一個子類,實現單線程阻塞的服務器。循環調用process處理數據。
3、TThreadedServer.h:繼承於TServer(提供serve入口)。每新到一個請求,則新建一個Task對象(Runnable),TThreadFactory根據Task對象生成一個線程,然后運行。所以此類與TSimpleServer的單線程阻塞式不一樣,此類對每一個請求開啟一個新線程處理。
4、TThreadedPoolServer.h/.cpp:內部使用ThreadManager來管理線程和任務,TThreadedPoolServer只是實現了TServer的相關內容,核心都在ThreadManager中。
5、TNonblockingServer.h/.cpp:使用了libevent的異步模型。非阻塞服務器。libevent性能有待研究。內部也可以使用ThreadManager,如果使用ThreadManager則上TThreadedMangePoolServer一樣了。