Thrift框架快速入門


Thrift介紹
1.什么是thrift?
thrift早期由facebook內部團隊開發,主要用於實現跨語言間的方法調用,屬於遠程方法調用的一種,后開源納入apache中,成為了apache thrift項目。
thrift允許定義一個簡單的定義文件中的數據類型和服務接口,以作為輸入文件,編譯器生成代碼用來方便地生成RPC客戶端和服務器通信的無縫跨編程語言。

2.什么是RPC?
RPC (Remote Procedure Call Protocol),遠程過程調用協議。

 

簡單的說,RPC就是從一台機器(客戶端)上通過參數傳遞的方式調用另一台機器(服務器)上的一個函數或方法並得到返回的結果。
RPC 會隱藏底層的通訊細節(不需要直接處理Socket通訊或Http通訊) RPC 是一個請求響應模型。
客戶端發起請求,服務器返回響應(類似於Http的工作方式) RPC 在使用形式上像調用本地函數(或方法)一樣去調用遠程的函數(或方法)。

Thrift棧結構

 

Thrift數據類型
基本類型
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:未知編碼文本或二進制字符串,對應 Java 的 String
結構體類型
struct:定義公共的對象,類似於 C 語言中的結構體定義,在 Java 中是一個 JavaBean
容器類型
list:對應 Java 的 ArrayList
set:對應 Java 的 HashSet
map:對應 Java 的 HashMap
異常類型
exception:對應 Java 的 Exception
服務類型
service:對應服務的類

生成thrift的java代碼
http://thrift.apache.org/download

namespace java service.demo
service Hello{        
	string helloString(1:string para)        
	i32 helloInt(1:i32 para)        
	bool helloBoolean(1:bool para)        
	void helloVoid()        
	string helloNull()
}

 

 

 

Hello.java內容
(1)異步客戶端類AsyncClient和異步接口AsyncIface
(2)同步客戶端類Client和同步接口Iface,Client類繼承自TServiceClient,並實現了同步接口Iface;Iface就是根據thrift文件中所定義的接口函數所生成;Client類是在開發Thrift的客戶端程序時使用,Client類是Iface的客戶端存根實現, Iface在開發Thrift服務器的時候要使用,Thrift的服務器端程序要實現接口Iface。
 (3)Processor類,該類主要是開發Thrift服務器程序的時候使用,該類內部定義了一個map,它保存了所有函數名到函數對象的映射,一旦Thrift接到一個函數調用請求,就從該map中根據函數名字找到該函數的函數對象,然后執行它;
 (4)參數類,為每個接口函數定義一個參數類,例如:為接口helloInt產生一個參數類:helloInt_args,一般情況下,接口函數參數類的命名方式為:接口函數名_args;
(5)返回值類,每個接口函數定義了一個返回值類,例如:為接口helloInt產生一個返回值類:helloInt_result,一般情況下,接口函數返回值類的命名方式為:接口函數名_result;

參數類和返回值類中有對數據的讀寫操作,在參數類中,將按照協議類將調用的函數名和參數進行封裝,在返回值類中,將按照協議規定讀取數據。

 Client

 Iface

 

HelloServiceImpl

 

調用過程

Thrift調用過程中,Thrift客戶端和服務器之間主要用到傳輸層類、協議層類和處理類三個主要的核心類,這三個類的相互協作共同完成rpc的整個調用過程

(1)     將客戶端程序調用的函數名和參數傳遞給協議層(TProtocol),協議層將函數名和參數按照協議格式進行封裝,然后封裝的結果交給下層的傳輸層。此處需要注意:要與Thrift服務器程序所使用的協議類型一樣,否則Thrift服務器程序便無法在其協議層進行數據解析;
 (2)    傳輸層(TTransport)將協議層傳遞過來的數據進行處理,例如傳輸層的實現類TFramedTransport就是將數據封裝成幀的形式,即“數據長度+數據內容”,然后將處理之后的數據通過網絡發送給Thrift服務器;此處也需要注意:要與Thrift服務器程序所采用的傳輸層的實現類一致,否則Thrift的傳輸層也無法將數據進行逆向的處理;
 (3)   Thrift服務器通過傳輸層(TTransport)接收網絡上傳輸過來的調用請求數據,然后將接收到的數據進行逆向的處理,例如傳輸層的實現類TFramedTransport就是將“數據長度+數據內容”形式的網絡數據,轉成只有數據內容的形式,然后再交付給Thrift服務器的協議類(TProtocol);
 (4)  Thrift服務端的協議類(TProtocol)將傳輸層處理之后的數據按照協議進行解封裝,並將解封裝之后的數據交個Processor類進行處理;

(5)   Thrift服務端的Processor類根據協議層(TProtocol)解析的結果,按照函數名找到函數名所對應的函數對象;
 (6)   Thrift服務端使用傳過來的參數調用這個找到的函數對象;
 (7)   Thrift服務端將函數對象執行的結果交給協議層;
 (8)   Thrift服務器端的協議層將函數的執行結果進行協議封裝;
 (9)   Thrift服務器端的傳輸層將協議層封裝的結果進行處理,例如封裝成幀,然后發送給Thrift客戶端程序;
(10)  Thrift客戶端程序的傳輸層將收到的網絡結果進行逆向處理,得到實際的協議數據;
(11)  Thrift客戶端的協議層將數據按照協議格式進行解封裝,然后得到具體的函數執行結果,並將其交付給調用函數;

服務端

客戶端

輸出結果

 

 

協議和傳輸方式

Thrift 可以讓用戶選擇客戶端與服務端之間傳輸通信協議的類別,在傳輸協議上總體划分為文本 (text) 和二進制 (binary) 傳輸協議,為節約帶寬,提高傳輸效率,一般情況下使用二進制類型的傳輸協議為多數,有時還會使用基於文本類型的協議,這需要根據項目 / 產品中的實際需求。常用協議有以下幾種:
TBinaryProtocol:是Thrift的默認協議,使用二進制編碼格式進行數據傳輸,基本上直接發送原始數據
TCompactProtocol:壓縮的、密集的數據傳輸協議,基於Variable-length quantity的zigzag 編碼格式
TJSONProtocol:以JSON (JavaScript Object Notation)數據編碼協議進行數據傳輸
TDebugProtocol:常常用以編碼人員測試,以文本的形式展現方便閱讀

常用的傳輸層有以下幾種:
TSocket —— 使用阻塞式 I/O 進行傳輸,是最常見的模式
TFramedTransport —— 使用非阻塞方式,按塊的大小進行傳輸,類似於 Java 中的 NIO
TNonblockingTransport —— 使用非阻塞方式,用於構建異步客戶端
TServerSocket:非阻塞型 socket,用於服務器端,accecpt 到的 socket 類型都是 TSocket(即阻塞型 socket)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM