Thirft架構快速入門,thirft快速入門
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.demoservice 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)