Thrift由Facebook研發,主要用於各個服務之間的RPC通訊(與上篇博客:gRPC同類),支持跨語言,經常使用的語言好比C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml都支持。Thrift是一個典型的 CS(客戶端/服務端) 結構,在服務器端實現代碼,提供接口;客戶端能夠直接調用接口,客戶端和服務端可使用不一樣的語言開發。既然客戶端和服務端能使用不一樣的語言開發,那麼必定就要有一種中間語言來關聯客戶端和服務端的語言,沒錯,這種語言就是IDL(Interface Description Language)html
# 下載安裝包 curl -# -O http://archive.apache.org/dist/thrift/0.9.2/thrift-0.9.2.tar.gz # 下載完成後開始解壓 tar zxvf thrift-0.9.2.tar.gz # 進入文件夾 cd thrift-0.9.2 # 初始化配置 ./configure # 開始構建 make # 必定要用sudo,本機編譯 sudo make install # 查看thrift是否生效 thrift --version # 顯示:Thrift version 0.9.2
brew install thrift
pip install thrift
明確要交互的數據格式和具體的方法,定義出thrift接口描述文件,以thrift爲後綴(英文叫作IntefaceDescription File)python
調用thrift工具,依據thrift接口文件,生成RPC代碼;c++
服務器端程序引用thrift生成的RPC代碼,並實現thrift中定義的邏輯,而後啓動監聽,等待客戶端發來請求。git
Thrift類型系統包括預約義的基本類型,用戶自定義結構體,容器類型,異常和服務定義。github
Thrift結構體類型在概念上相似於C語言中結構體類型,Thrift結構體將會被轉換成面嚮對象語言中的類。
```c++
struct People {
1: required string name;
2: required i32 age = 20;
3: optional string sex;
}shell
能夠看到,結構體中每個域都有一個正整數標識符,這個標識符並不要求連續,但一旦定義,不建議再進行修改 另外,每一個域前都會有required或optional的限定,前者表示是必填域,後者則表示是可選域。域是能夠有默認值的,好比上例中的「age"。 若是一個域設置爲optional且在構造結構體時沒有給這個域賦值,那麼在使用這個結構體時,就會忽略掉這個optional的域 #### 異常(Exceptions) 異常在語法和功能上相似於結構體,一個差異是異常使用關鍵字exception而不是struct來聲明。但他們在語義上有明顯不一樣之處:當定義一個RPC服務時,咱們能夠聲明一個遠程方法可以拋出一個異常。 ```c++ exception RequestException { 1: i32 code; 2: string reason; }
服務的定義,與面向對象技術中定義一個接口很相似,而這些接口其實就是純虛函數。thrift編譯工具會根據服務的定義來產生相應的方法和函數。
每一個服務,都包括了若干個函數,每一個函數包括了若干參數和一個返回值(返回值能夠是void.
(小技巧:返回值爲void的函數,你能夠在函數名前加上oneway標識符,將此函數以異步模式執行,這樣在調用此函數後,函數會當即返回。)apache
對於返回void的函數,thrift仍然會確保函數返回,這樣就表示這個函數已被正確執行,且服務器端已有返回信息了。可是若是給void的函數前加上oneway,那麼此函數的返回只能表示數據已經進入傳輸層,並不能表示服務器端已經收到並返回了數據數組
```c++
service vulgar_detect{
bool is_vulgar(1:string title),
i32 calc(1: i32 num)
}服務器
##### 傳輸協議 在傳輸協議上整體劃分爲文本和二進制 ,爲節約帶寬,提升傳輸效率,通常狀況下使用二進制類型的傳輸協議爲多數. * TBinaryProtocol — 二進制編碼格式進行數據傳輸 * TCompactProtocol — 高效率的、密集的二進制編碼格式進行數據傳輸 * TJSONProtocol — 使用 JSON 的數據編碼協議進行數據傳輸 * TSimpleJSONProtocol — 只提供 JSON 只寫的協議,適用於經過腳本語言解析 * TDebugProtocol – 使用易懂的可讀的文本格式,以便於 debug ##### 數據傳輸 * TSocket — 使用阻塞式 I/O 進行傳輸,是最多見的模式 * TFramedTransport — 使用非阻塞方式,按塊的大小進行傳輸 * TNonblockingTransport — 使用非阻塞方式,用於構建異步客戶端 * TMemoryTransport – 將內存用於 I/O * TZlibTransport – 使用 zlib 進行壓縮, 與其餘傳輸方式聯合使用 * TFileTransport – 以文件形式進行傳輸 ##### 服務端類型 * TSimpleServer — 單線程服務器端使用標準的阻塞式 I/O * TThreadPoolServer —— 多線程服務器端使用標準的阻塞式 I/O * TNonblockingServer —— 多線程服務器端使用非阻塞式 I/O #### thrift編譯工具 在咱們編寫好thrift接口描述文件以後,thrift編譯工具就要派上用場了,它的做用就是根據thrift接口描述文件來生成相應開發語言的RPC代碼. 在終端下輸入: ```shell thrift --gen ${開發語言} ${thrift接口描述文件}
關於thrift的更多命令能夠輸入:多線程
thrift --help
```c++
namespace py example
struct Data {
1: string text
2: i32 id
}
service format_data {
Data do_format(1:Data data),
}
2. 用thrift命令編譯example.thrift文件生成python代碼 ```shell thrift -out . --gen py example.thrift # 參數說明: -out .:表示生成的代碼在當前目錄,而且命名不帶gen-前綴,若是用-o參數是帶有gen-前綴的
這一步生成的代碼結構以下圖:
參考服務端客戶端源代碼Github,或者直接git clone
python server.py
,再運行客戶端python client.py
,輸入以下:>>>client-requets >>>server-answer Data(text='HELLO,WORLD!', id=123)