第一篇blog,歡迎大家批評指正。
一 前言
Thrift是facebook技術核心框架之一,不同開發語言開發的服務可以通過該框架實現通信。Thrift通過接口定義語言 (interface definition language,IDL) 來定義數據類型和服務,Thrift接口定義文件由Thrift代碼編譯器生成thrift目標語言的代碼(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),并由生成的代碼負責RPC協議層和傳輸層的實現。
簡而言之,開發者只需準備一份thrift腳本,通過thrift code generator(像gcc那樣輸入一個命令)就能生成所要求的開發語言代碼。不支持windows。
Thrift側重點是構建跨語言的可伸縮的服務,特點就是支持的語言多,同時提供了完整的RPC service framework,可以很方便的直接構建服務,不需要做太多其他的工作。服務端可以根據需要編譯成simple | thread-pool | threaded | nonblocking等方式;
本文檔參考: Thrift types , Thrift IDL , Thrift:The Missing Guide .
二 語法參考
2.1 類型
Thrift類型系統包括預定義基本類型,用戶自定義結構體,容器類型,異常和服務定義。
2.1.1 基本類型
-
bool : 布爾值 (true or false), one byte
-
byte : 有符號字節
-
i16 : 16位有符號整型
-
i32 : 32位有符號整型
-
i64 : 64位有符號整型
-
double : 64位浮點型
-
string : Encoding agnostic text or binary string
Note that: Thrift不支持無符號整型,因為Thrift目標語言沒有無符號整型,無法轉換。
2.1.2 容器(Containers)
Thrift容器與流行編程語言的容器類型相對應,采用Java泛型風格。它有3種可用容器類型:
-
list<t1> : 元素類型為t1的有序表,容許元素重復。(有序表ordered list不知道如何理解?排序的?c++的vector不排序)
-
set<t1> :元素類型為t1的無序表,不容許元素重復。
-
map<t1,t2> : 鍵類型為t1,值類型為t2的kv對,鍵不容許重復。
容器中元素類型可以是除了service外的任何合法Thrift類型(包括結構體和異常)。
2.1.3 結構體和異常(Structs and Exceptions)
Thrift結構體在概念上類似于(similar to)C語言結構體類型--將相關屬性封裝在一起的簡便方式。Thrift結構體將會被轉換成面向對象語言的類。
異常在語法和功能上類似于(equivalent to)結構體,差別是異常使用關鍵字exception而不是struct聲明。但它在語義上不同于結構體:當定義一個RPC服務時,開發者可能需要聲明一個遠程方法拋出一個異常。
結構體和異常的聲明將在下一節介紹。
2.1.4 服務(Services)
服務的定義方法在語義(semantically)上等同于面向對象語言中的接口。Thrift編譯器會產生執行這些接口的client和server stub。具體參見下一節。
2.2 類型定義(Typedef)
Thrift支持C/C++類型定義。
typedef i32 MyInteger // a
typedef T ReT // b
說明:a.? 末尾沒有逗號。b.?? struct也可以使用typedef。
2.3 枚舉(Enums)
很多語言都有枚舉,意義都一樣。比如,當定義一個消息類型時,它只能是預定義的值列表中的一個,可以用枚舉實現。
enum TweetType {
TWEET, // (1 )
? RETWEET = 2 , // (2 )
DM = 0xa , // ( 3 )
? REPLY
} // ( 4 )
struct Tweet {
1 : required i32 userId;
2 : required string userName;
3 : required string text;
4 : optional Location loc;
5 : optional TweetType tweetType = TweetType.TWEET; // (5)
16 : optional string language = " english "
}
說明:
(1).? 編譯器默認從0開始賦值
(2).? 可以賦予某個常量某個整數
(3).? 允許常量是十六進制整數
(4).? 末尾沒有分號
(5).? 給常量賦缺省值時,使用常量的全稱
注意,不同于protocal buffer,thrift不支持枚舉類嵌套,枚舉常量必須是32位的正整數
2.4 注釋(Comment)
Thrift支持shell風格, C多行風格和Java/C++單行風格。
# This is a valid comment.
/*
* This is a multi-line comment.
* Just like in C.
*/
// C++/Java style single-line comments work just as well.
2.5 名字空間(Namespace)
Thrift中的命名空間類似于C++中的namespace和java中的package,它們提供了一種組織(隔離)代碼的簡便方式。名字空間也可以用于解決類型定義中的名字沖突。
由于每種語言均有自己的命名空間定義方式(如python中有module), thrift允許開發者針對特定語言定義namespace:
namespace cpp com.example.project // (1)
namespace java com.example.project // (2)
namespace php com.example.project
(1). 轉化成namespace com { namespace example { namespace project {
(2).? 轉換成package com.example.project
2.6 Includes
便于管理、重用和提高模塊性/組織性,我們常常分割Thrift定義在不同的文件中。包含文件搜索方式與c++一樣。Thrift允許文件包含其它thrift文件,用戶需要使用thrift文件名作為前綴訪問被包含的對象,如:
include " tweet.thrift " // (1)
...
struct TweetSearchResult {
1 : tweet.Tweet tweet; // (2)
}
說明:
(1).? thrift文件名要用雙引號包含,末尾沒有逗號或者分號
(2).? 注意tweet前綴
2.7 常量(Constant)
Thrift允許定義跨語言使用的常量,復雜的類型和結構體可使用JSON形式表示。
const i32 INT_CONST = 1234 ; // (1)
說明:
(1) 分號可有可無。支持16進制。
2.8 結構體定義(Defining Struct)
struct是Thrift IDL中的基本組成塊,由域組成,每個域有唯一整數標識符,類型,名字和可選的缺省參數組成。如定義一個類似于Twitter服務:
struct Tweet {
1 : required i32 userId; // (1)
2 : required string userName; // (2)
3 : required string text;
4 : optional Location loc; // (3)
16 : optional string language = " english " // (4)
}
struct Location { // (5)
1 : required double latitude;
2 : required double longitude;
}
?(1) 每個域有一個唯一的正整數標識符;
?(2) 每個域可標識為required或optional;
?(3) 結構體可以包含其它結構體
?(4) 域可有默認值,與required或optional無關。
?(5) Thrift文件可以定義多個結構體,并在同一文件中引用,也可加入文件限定詞在其它Thrift文件中引用。
如上所見,消息定義中的每個域都有一個唯一數字標簽,這些數字標簽在傳輸時用來確定域,一旦使用消息類型,標簽不可改變。( 隨著項目的進展,可以要變更Thrift文件,最好不要改變原有的數字標簽 )
規范的struct定義中的每個域均會使用required或者optional關鍵字進行標識。如果required標識的域沒有賦值,Thrift將給予提示;如果optional標識的域沒有賦值,該域將不會被序列化傳輸;如果某個optional標識域有缺省值而用戶沒有 重 新賦值,則該域的值一直為缺省值;如果 某個optional標識域有缺省值或者用戶 已經重 新賦值,而不設置它的__isset為true,也不會被序列化傳輸。(不被序列化傳輸的后果是什么?為空為零?還是默認值,下次試試)
與services不同,結構體不支持繼承。
2.9 服務定義(Defining Services)
在流行的序列化/反序列化框架(如protocal buffer)中,Thrift是少有的提供多語言間RPC服務的框架。這是Thrift的一大特色。
Thrift編譯器會根據選擇的目標語言為server產生服務接口代碼,為client產生stubs。
service Twitter {
// A method definition looks like C code. It has a return type, arguments,
// and optionally a list of exceptions that it may throw. Note that argument
// lists and exception list are specified using the exact same syntax as
// field lists in structs.
void ping(), // (1)
bool postTweet( 1 :Tweet tweet); // (2)
TweetSearchResult searchTweets( 1 : string query); // (3)
// The 'oneway' modifier indicates that the client only makes a request and
// does not wait for any response at all. Oneway methods MUST be void.
oneway void zip() // (4)
}
Note that:參數列表的定義與結構體一樣。服務支持繼承。
慢慢寫,下次繼續
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
