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,用於伺服器端,accecpt 到的socket 類型都是TSocket(即阻塞類型socket)
以上是Thrift框架快速入門方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!