Thrift使用和原理

Thrift是一種支持多語言的軟件框架,在各個服務之間的RPC通信領域應用非常廣泛。RPC(遠程過程調用)是一個計算機通信協議,該協議允許運行於一臺計算機的程序調用另一臺計算機的子程序,而程序員無需額外地爲這個交互作用編程。(參考遠程過程調用)。

Thrift通過一箇中間語言(IDL, 接口定義語言)來定義RPC的接口和數據類型,然後通過一個編譯器生成不同語言的代碼(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),並由生成的代碼負責RPC協議層和傳輸層的實現。

一、核心組件和特點

Thrift的核心組件有:

  1. TProtocol 協議和編解碼組件
  2. TTransport 傳輸組件
  3. TProcessor 服務調用組件
  4. TServer,Client 服務器和客戶端組件
  5. IDL 服務描述組件,負責生產跨平臺客戶端

作爲一個高性能的RPC框架,Thrift的主要特點有:

  1. 基於二進制的高性能的編解碼框架
  2. 基於NIO的底層通信
  3. 相對簡單的服務調用模型
  4. 使用IDL支持跨平臺調用

二、Thrift Type

Thrift Type包含了基本類型,自定義的結構體,容器,異常等,以下內容主要來自https://matt33.com/2016/04/07/thrift-learn/

2.1 基本類型(Base Types)

  • bool: 布爾變量(A boolean value, one byte);
  • byte: 8位有符號整數(A signed byte);
  • i16: 16位有符號整數(A 16-bit signed integer);
  • i32: 32位有符號整數(A 32-bit signed integer);
  • i64: 64位有符號整數(A 64-bit signed integer);
  • double: 64位浮點數(A 64-bit floating point number);
  • binary: byte數組(A byte array);
  • string: 字符串(Encoding agnostic text or binary string);

2.2 容器類型(Containers)

  • list: 一系列由T類型的數據組成的有序列表,元素可以重複;
  • set: 一系列由T類型的數據組成的無序集合,元素不可重複
  • map: 一個字典結構,key爲T1類型,value爲T2類型;

2.3 結構體(Struct)

結構體中包含一系列的強類型域,等同於無繼承的class。可以看出struct寫法很類似C語言的結構體。

struct Example {
  1:i32 number=10,
  2:i64 bigNumber,
  3:list<double> decimals,
  4:string name="thrifty"
}

2.4 可選與必選

Thrift提供兩個關鍵字required,optional,分別用於表示對應的字段時必填的還是可選的。例如:

struct People {
    1: required string name;
    2: optional i32 age;
}

表示name是必填的,age是可選的。

2.5 聯合(Union)

在一個結構體中,如果field之間的關係是互斥的,即只能有一個field被使用被賦值。在這種情況下,我們可以使用union來聲明這個結構體,而不是一堆堆optional的field,語意上也更明確了。例如:

union JavaObjectArg {
  1: i32 int_arg;
  2: i64 long_arg;
  3: string string_arg;
  4: bool bool_arg;
  5: binary binary_arg;
  6: double double_arg;
}

三、RPC 調用分以下兩種:

  • 同步調用:客戶方等待調用執行完成並返回結果。
  • 異步調用:客戶方調用後不用等待執行結果返回,但依然可以通過回調通知等方式獲取返回結果。若客戶方不關心調用返回結果,則變成單向異步調用,單向調用不用返回結果。

四、Thrift模型

在這裏插入圖片描述
如上圖架構中各個層級,我們看其中的兩個

4.1 協議層(傳輸格式)

  • TBinaryProtocol: 二進制格式;
  • TCompactProtocol:高效率的、密集的二進制編碼格式進行數據傳輸;
  • TJSONProtocol:JSON格式;
  • TSimpleJSONProtocol:提供JSON只寫協議, 生成的文件很容易通過腳本語言解析;
  • TDebugProtocol:使用易懂的可讀的文本格式,以便於debug。

4.2 傳輸層(數據傳輸方式)

  • TSocket:阻塞式socker;
  • TFramedTransport:使用非阻塞方式,以frame爲單位進行傳輸。
  • TFileTransport:以文件形式進行傳輸。
  • TMemoryTransport:將內存用於I/O. java實現時內部實際使用了簡單的ByteArrayOutputStream。
  • TZlibTransport:使用zlib進行壓縮, 與其他傳輸方式聯合使用。當前無java實現。
  • TNonblockingTransport —— 使用非阻塞方式,用於構建異步客戶端

4.3 服務模型

  • TSimpleServer:單線程服務器端使用標準的阻塞式 I/O,簡單的單線程服務模型,常用於測試;
  • TThreadPoolServer:多線程服務模型,使用標準的阻塞式IO;
  • TNonblockingServer:多線程服務模型,使用非阻塞式IO(需使用TFramedTransport數據傳輸方式)。

4.4 Thrift RPC過程:

Client端通過Client Stub將接口、方法、參數按照協議規定的進行編碼,並且通過網絡傳輸到Server端。Server端的收到請求後交給Server Stub進行解碼併發起後端調用,最終將執行結果返回Client

更詳細的過程:
  (1). client代碼像普通函數調用一樣調用client stub函數,這個調用是本地調用,調用參數會和平常函數調用一樣進行返回地址和調用參數壓棧操作;
  (2). client stub會把調用參數和其它信息(比如調用方法名、調用屬性等,可以稱爲metadata)進行打包封裝成message,然後通過系統調用發送該message,這個打包的過程是個序列化的過程;
  (3). client尋求到服務端的地址,然後通過本地操作系統經由某種協議,將上述message發送給server端;
  (4). server端的操作系統接收message後將其傳遞給server stub;
  (5). server stub將message解包,得到原始傳遞過來的各項調用參數,解包的過程是反序列化的過程;
  (6). server stub調用server端的本地函數,然後將得到的結果按照上述類似的步驟反向傳遞給client作爲結果返回。當然整個過程也可能不那麼順利,那麼也應該產生合適的狀態碼、異常信息作爲返回。
 所以RPC實際是通過client stub和server stub起到一個代理的作用,將client的請求轉發到server端去操作,並將操作得到的結果回傳,因爲傳遞是跨進程、跨主機的,所以必須進行序列化和反序列化的過程來保證消息的正確性。關於stub的概念:https://www.jianshu.com/p/9ccdea882688

4.5 影響RPC性能點有哪些

  • 傳輸協議:HTTP、TCP、UDP
  • 序列化方案:Java自帶的序列化、其他序列化框架Protobuf、Kryo、Hession
  • 工作模式:同步or異步

五、安裝使用

關於安裝過程可以參考 https://juejin.im/post/5b290dbf6fb9a00e5c5f7aaa和https://matt33.com/2016/04/07/thrift-learn/這兩篇文章

編寫一個thrift文件,定義服務端的接口定義個服務接口

namespace java com.momo.learn.learn.thrift

struct Param{
	1: required i32 id;
	2: required string name;
    3: optional i32 age;
}

service HelloThriftService {
 i32 hello(1:string param1, 2:Param param2, 3:map<string,string> param3);
}

執行下邊命令

thrift —gen java HelloThriftService.thrift

會看到下邊這個圖,相當於定義了接口的簽名,服務端和客戶端分別實現和引用接口就可以完成使用

在這裏插入圖片描述
參考文章:

http://thrift.apache.org/

https://juejin.im/post/5b290dbf6fb9a00e5c5f7aaa

https://matt33.com/2016/04/07/thrift-learn/

https://blog.csdn.net/mindfloating/article/details/39474123

重點推薦:https://www.kancloud.cn/digest/thrift/118986

發佈了224 篇原創文章 · 獲贊 337 · 訪問量 86萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章