Thrift最初由Facebook研發,主要用于各個服務之間的RPC通信,支持跨語言,常用的語言比如C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml都支持。
thrift idl compiler
thrift 通過idl(interface define language)將通用的thrift解析成對應的語言,比如java,用戶直接應用并且實現自已需要的接口即可,相當的方便。
thrift idl支持的類型
基本類型
thrift不支持無符號類型,因為很多編程語言不存在無符號類型,比如java
- byte: 有符號字節
- i16: 16位有符號整數
- i32: 32位有符號整數
- i64: 64位有符號整數
- double: 64位浮點數
- string: 字符串
容器類型
集合中的元素可以是除了service之外的任何類型,包括exception。
- list<T>: 一系列由T類型的數據組成的有序列表,元素可以重復
- set<T>: 一系列由T類型的數據組成的無序集合,元素不可重復
- map<K, V>: 一個字典結構,key為K類型,value為V類型,相當于Java中的HashMap<K,V>
結構體(struct)
就像C語言一樣,thrift也支持struct類型,目的就是將一些數據聚合在一起,方便傳輸管理。struct的定 義形式如下:
struct People {
1: string name;
2: i32 age;
3: string sex;
}
枚舉(enum)
枚舉的定義形式和Java的Enum定義差不多,例如:
enum Sex {
MALE,
FEMALE
}
異常(exception)
thrift支持自定義exception,規則和struct一樣,如下:
exception RequestException {
1: i32 code;
2: string reason;
}
服務(service)
thrift定義服務相當于Java中創建Interface一樣,創建的service經過代碼生成命令之后就會生成客戶端和服務端的框架代碼。定義形式如下:
service HelloWordService {
// service中定義的函數,相當于Java interface中定義的函數
string doAction(1: string name, 2: i32 age);
}
類型定義
thrift支持類似C++一樣的typedef定義,比如:
typedef i32 Integer
typedef i64 Long
注意,末尾沒有逗號或者分號
常量(const)
thrift也支持常量定義,使用const關鍵字,例如:
const i32 MAX_RETRIES_TIME = 10
const string MY_WEBSITE = "http://qifuguang.me";
末尾的分號是可選的,可有可無,并且支持16進制賦值
命名空間
thrift的命名空間相當于Java中的package的意思,主要目的是組織代碼。thrift使用關鍵字namespace定義命名空間,例如:
namespace java com.winwill.thrift
格式是:namespace 語言名 路徑, 注意末尾不能有分號。
文件包含
thrift也支持文件包含,相當于C/C++中的include,Java中的import。使用關鍵字include定義,例 如:
include "global.thrift"
注釋
thrift注釋方式支持shell風格的注釋,支持C/C++風格的注釋,即#和//開頭的語句都單當做注釋,/**/包裹的語句也是注釋。
可選與必選
thrift提供兩個關鍵字required,optional,分別用于表示對應的字段時必填的還是可選的。例如:
struct People {
1: required string name;
2: optional i32 age;
}
表示name是必填的,age是可選的。
生成代碼
知道了怎么定義thirtf文件之后,我們需要用定義好的thrift文件生成我們需要的目標語言的源碼,本文以生成java源碼為例。假設現在定義了如下一個thrift文件:
namespace java com.payne
enum RequestType {
SAY_HELLO, //問好
QUERY_TIME, //詢問時間
}
struct Request {
1: required RequestType type; // 請求的類型,必選
2: required string name; // 發起請求的人的名字,必選
3: optional i32 age; // 發起請求的人的年齡,可選
}
exception RequestException {
1: required i32 code;
2: optional string reason;
}
// 服務名
service HelloWordService {
string doAction(1: Request request) throws (1:RequestException qe); // 可能拋出異常。
}
在終端運行如下命令(前提是已經安裝thrift):
thrift -r --gen java Test.thrift
則在當前目錄會生成一個gen-java目錄,該目錄下會按照namespace定義的路徑名一次一層層生成文件夾,到gen-java/com/payne/目錄下可以看到生成的4個Java類: