介紹
Thrift是一個軟件框架,用來進行可擴展且跨語言的服務的開發。它結合了功能強大的軟件堆棧和代碼生成引擎,以構建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等編程語言間無縫結合的、高效的服務。
服務模型
thrift是一個支持多語言之間遠程函數調用的開源工具,因為其方便的使用和對c++、java、php等多種主流語言的支持而獲得廣泛地使用。server層屬于其接受客戶端請求的服務模型層,用于處理接受客戶端過來的請求。
現在支持三種模型:
(1)單線程模型,主線程監聽socket、獲得連接請求、處理請求
(2)多線程模型,主線程監聽socket,獲得新連接,使用threadFactory創建新線程處理該連接直到連接斷開
(3)線程池模型,主線程處理通信請求將獲得的新連接fd生成TConnectedClient加入任務隊列;多個工作線程(ThreadManager管理)從任務隊列取連接、處理請求,直到連接斷開,再從隊列取新的連接
總結
3種服務模型個有優劣,單線程模型一般只用在調試環境中,同時刻只能處理一個連接;多線程模型同時可以處理多個新連接,但每次處理新的連接都會新建線程,存在不小的開銷;線程池模型一開始就創建好線程,減小了創建線程、銷毀線程開銷,但是多了維護隊列、固定數目線程的開銷。
結構說明:
如上圖所示,
TServerFramework是3個服務模型類的基類,通過serve方法提供了處理所有連接請求的循環邏輯,而TSimpleServer、TThreadedServer和TThreadPoolServer三個類分別對應3中服務模型。
TConnectedClient類存儲了連接到服務端的客戶端的相關信息,提供了處理一個請求的方法run,此類繼承于Runnable。
實現
TServerFramework - 提供統一處理循環
mon_限制并發客戶端數量Monitor
clients_并發客戶端數量int64_t
hwm_并發最高值int64_t
limit_并發限制值int64_t
serve方法
循環地從TServerTransport接收clients,通過調用newlyConnectedClient方法送去處理。
newlyConnectedClient調用onClientConnected方法處理連接請求,綁定disposeConnectedClient方法處理連接銷毀,并控制并發連接數。
每個不同的服務模型類提供不同的onClientConnected來實現不同的服務模型。
TSimpleServer - 單線程服務模型
onClientConnected方法
直接調用TConnectedClient的run方法處理請求
TThreadedServer - 多線程服務模型
serve方法
調用TServerFramework的serve,啟動多線程服務模型入口
onClientConnected方法
每到來一個新的連接,都新建一個線程使用TConnectedClient的run進行處理
TThreadPoolServer - 線程池服務模型
threadManager_線程管理ThreadManader
stop_voatile bool
timeout_等待任務數超限時的超時時間volatile int64_t
taskExpiration_任務過期時間volatile int64_t
serve方法
調用TServerFramework的serve,啟動多線程服務模型入口
threadManager->join等待threadManager的線程池中線程結束
onClientConnected方法
通過使用ThreadManager的add將新的連接請求放入任務隊列
實際處理要等到ThreadManager的Worker線程的run從任務隊列取任務,執行TConnectedClient的run方法。
TNonblockingServer 服務模型
使用非阻塞式IO,服務端和客戶端需要指定TFramedTransport數據傳輸的方式。
THsHaServer服務模型
半同步半異步的服務端模型,需要指定為:TFramedTransport數據傳輸的方式。
TConnectedClient - 連接TServer的客戶端
processor_處理類TProcessor
inputProtocol_輸入協議TProtocol
outputProtocol_輸出協議TProtocol
eventHandler_TServerEventHandler
client_客戶端請求TTransport
opaqueContext_從eventHandler_獲取的上下文void*
run方法
處理一個連接上的請求,直到連接斷開
使用processor的process方法
數據類型
基本類型:
bool:布爾值,true 或 false,對應 Java 的 boolean
byte:8 位有符號整數,對應 Java 的 byte
i16:16 位有符號整數,對應 Java 的 short
i32:32 位有符號整數,對應 Java 的 int
i64:64 位有符號整數,對應 Java 的 long
double:64 位浮點數,對應 Java 的 double
string:utf-8編碼的字符串,對應 Java 的 String
結構體類型:
struct:定義公共的對象,類似于 C 語言中的結構體定義,在 Java 中是一個 JavaBean
容器類型:
list:對應 Java 的 ArrayList
set:對應 Java 的 HashSet
map:對應 Java 的 HashMap
異常類型:
exception:對應 Java 的 Exception
服務類型:
service:對應服務的類
服務端編碼基本步驟:
實現服務處理接口impl
創建TProcessor
創建TServerTransport
創建TProtocol
創建TServer
啟動Server
客戶端編碼基本步驟:
創建Transport
創建TProtocol
基于TTransport和TProtocol創建 Client
調用Client的相應方法
數據傳輸協議
TBinaryProtocol : 二進制格式.
TCompactProtocol : 壓縮格式
TJSONProtocol : JSON格式
TSimpleJSONProtocol : 提供JSON只寫協議, 生成的文件很容易通過腳本語言解析
tips:客戶端和服務端的協議要一致