第一篇blog,歡迎大家批評(píng)指正。
一 前言
Thrift是facebook技術(shù)核心框架之一,不同開(kāi)發(fā)語(yǔ)言開(kāi)發(fā)的服務(wù)可以通過(guò)該框架實(shí)現(xiàn)通信。Thrift通過(guò)接口定義語(yǔ)言 (interface definition language,IDL) 來(lái)定義數(shù)據(jù)類(lèi)型和服務(wù),Thrift接口定義文件由Thrift代碼編譯器生成thrift目標(biāo)語(yǔ)言的代碼(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),并由生成的代碼負(fù)責(zé)RPC協(xié)議層和傳輸層的實(shí)現(xiàn)。
簡(jiǎn)而言之,開(kāi)發(fā)者只需準(zhǔn)備一份thrift腳本,通過(guò)thrift code generator(像gcc那樣輸入一個(gè)命令)就能生成所要求的開(kāi)發(fā)語(yǔ)言代碼。不支持windows。
Thrift側(cè)重點(diǎn)是構(gòu)建跨語(yǔ)言的可伸縮的服務(wù),特點(diǎn)就是支持的語(yǔ)言多,同時(shí)提供了完整的RPC service framework,可以很方便的直接構(gòu)建服務(wù),不需要做太多其他的工作。服務(wù)端可以根據(jù)需要編譯成simple | thread-pool | threaded | nonblocking等方式;
本文檔參考: Thrift types , Thrift IDL , Thrift:The Missing Guide .
二 語(yǔ)法參考
2.1 類(lèi)型
Thrift類(lèi)型系統(tǒng)包括預(yù)定義基本類(lèi)型,用戶自定義結(jié)構(gòu)體,容器類(lèi)型,異常和服務(wù)定義。
2.1.1 基本類(lèi)型
-
bool : 布爾值 (true or false), one byte
-
byte : 有符號(hào)字節(jié)
-
i16 : 16位有符號(hào)整型
-
i32 : 32位有符號(hào)整型
-
i64 : 64位有符號(hào)整型
-
double : 64位浮點(diǎn)型
-
string : Encoding agnostic text or binary string
Note that: Thrift不支持無(wú)符號(hào)整型,因?yàn)門(mén)hrift目標(biāo)語(yǔ)言沒(méi)有無(wú)符號(hào)整型,無(wú)法轉(zhuǎn)換。
2.1.2 容器(Containers)
Thrift容器與流行編程語(yǔ)言的容器類(lèi)型相對(duì)應(yīng),采用Java泛型風(fēng)格。它有3種可用容器類(lèi)型:
-
list<t1> : 元素類(lèi)型為t1的有序表,容許元素重復(fù)。(有序表ordered list不知道如何理解?排序的?c++的vector不排序)
-
set<t1> :元素類(lèi)型為t1的無(wú)序表,不容許元素重復(fù)。
-
map<t1,t2> : 鍵類(lèi)型為t1,值類(lèi)型為t2的kv對(duì),鍵不容許重復(fù)。
容器中元素類(lèi)型可以是除了service外的任何合法Thrift類(lèi)型(包括結(jié)構(gòu)體和異常)。
2.1.3 結(jié)構(gòu)體和異常(Structs and Exceptions)
Thrift結(jié)構(gòu)體在概念上類(lèi)似于(similar to)C語(yǔ)言結(jié)構(gòu)體類(lèi)型--將相關(guān)屬性封裝在一起的簡(jiǎn)便方式。Thrift結(jié)構(gòu)體將會(huì)被轉(zhuǎn)換成面向?qū)ο笳Z(yǔ)言的類(lèi)。
異常在語(yǔ)法和功能上類(lèi)似于(equivalent to)結(jié)構(gòu)體,差別是異常使用關(guān)鍵字exception而不是struct聲明。但它在語(yǔ)義上不同于結(jié)構(gòu)體:當(dāng)定義一個(gè)RPC服務(wù)時(shí),開(kāi)發(fā)者可能需要聲明一個(gè)遠(yuǎn)程方法拋出一個(gè)異常。
結(jié)構(gòu)體和異常的聲明將在下一節(jié)介紹。
2.1.4 服務(wù)(Services)
服務(wù)的定義方法在語(yǔ)義(semantically)上等同于面向?qū)ο笳Z(yǔ)言中的接口。Thrift編譯器會(huì)產(chǎn)生執(zhí)行這些接口的client和server stub。具體參見(jiàn)下一節(jié)。
2.2 類(lèi)型定義(Typedef)
Thrift支持C/C++類(lèi)型定義。
typedef i32 MyInteger // a
typedef T ReT // b
說(shuō)明:a.? 末尾沒(méi)有逗號(hào)。b.?? struct也可以使用typedef。
2.3 枚舉(Enums)
很多語(yǔ)言都有枚舉,意義都一樣。比如,當(dāng)定義一個(gè)消息類(lèi)型時(shí),它只能是預(yù)定義的值列表中的一個(gè),可以用枚舉實(shí)現(xiàn)。
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 "
}
說(shuō)明:
(1).? 編譯器默認(rèn)從0開(kāi)始賦值
(2).? 可以賦予某個(gè)常量某個(gè)整數(shù)
(3).? 允許常量是十六進(jìn)制整數(shù)
(4).? 末尾沒(méi)有分號(hào)
(5).? 給常量賦缺省值時(shí),使用常量的全稱(chēng)
注意,不同于protocal buffer,thrift不支持枚舉類(lèi)嵌套,枚舉常量必須是32位的正整數(shù)
2.4 注釋?zhuān)–omment)
Thrift支持shell風(fēng)格, C多行風(fēng)格和Java/C++單行風(fēng)格。
# 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中的命名空間類(lèi)似于C++中的namespace和java中的package,它們提供了一種組織(隔離)代碼的簡(jiǎn)便方式。名字空間也可以用于解決類(lèi)型定義中的名字沖突。
由于每種語(yǔ)言均有自己的命名空間定義方式(如python中有module), thrift允許開(kāi)發(fā)者針對(duì)特定語(yǔ)言定義namespace:
namespace cpp com.example.project // (1)
namespace java com.example.project // (2)
namespace php com.example.project
(1). 轉(zhuǎn)化成namespace com { namespace example { namespace project {
(2).? 轉(zhuǎn)換成package com.example.project
2.6 Includes
便于管理、重用和提高模塊性/組織性,我們常常分割Thrift定義在不同的文件中。包含文件搜索方式與c++一樣。Thrift允許文件包含其它thrift文件,用戶需要使用thrift文件名作為前綴訪問(wèn)被包含的對(duì)象,如:
include " tweet.thrift " // (1)
...
struct TweetSearchResult {
1 : tweet.Tweet tweet; // (2)
}
說(shuō)明:
(1).? thrift文件名要用雙引號(hào)包含,末尾沒(méi)有逗號(hào)或者分號(hào)
(2).? 注意tweet前綴
2.7 常量(Constant)
Thrift允許定義跨語(yǔ)言使用的常量,復(fù)雜的類(lèi)型和結(jié)構(gòu)體可使用JSON形式表示。
const i32 INT_CONST = 1234 ; // (1)
說(shuō)明:
(1) 分號(hào)可有可無(wú)。支持16進(jìn)制。
2.8 結(jié)構(gòu)體定義(Defining Struct)
struct是Thrift IDL中的基本組成塊,由域組成,每個(gè)域有唯一整數(shù)標(biāo)識(shí)符,類(lèi)型,名字和可選的缺省參數(shù)組成。如定義一個(gè)類(lèi)似于Twitter服務(wù):
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) 每個(gè)域有一個(gè)唯一的正整數(shù)標(biāo)識(shí)符;
?(2) 每個(gè)域可標(biāo)識(shí)為required或optional;
?(3) 結(jié)構(gòu)體可以包含其它結(jié)構(gòu)體
?(4) 域可有默認(rèn)值,與required或optional無(wú)關(guān)。
?(5) Thrift文件可以定義多個(gè)結(jié)構(gòu)體,并在同一文件中引用,也可加入文件限定詞在其它Thrift文件中引用。
如上所見(jiàn),消息定義中的每個(gè)域都有一個(gè)唯一數(shù)字標(biāo)簽,這些數(shù)字標(biāo)簽在傳輸時(shí)用來(lái)確定域,一旦使用消息類(lèi)型,標(biāo)簽不可改變。( 隨著項(xiàng)目的進(jìn)展,可以要變更Thrift文件,最好不要改變?cè)械臄?shù)字標(biāo)簽 )
規(guī)范的struct定義中的每個(gè)域均會(huì)使用required或者optional關(guān)鍵字進(jìn)行標(biāo)識(shí)。如果required標(biāo)識(shí)的域沒(méi)有賦值,Thrift將給予提示;如果optional標(biāo)識(shí)的域沒(méi)有賦值,該域?qū)⒉粫?huì)被序列化傳輸;如果某個(gè)optional標(biāo)識(shí)域有缺省值而用戶沒(méi)有 重 新賦值,則該域的值一直為缺省值;如果 某個(gè)optional標(biāo)識(shí)域有缺省值或者用戶 已經(jīng)重 新賦值,而不設(shè)置它的__isset為true,也不會(huì)被序列化傳輸。(不被序列化傳輸?shù)暮蠊鞘裁矗繛榭諡榱悖窟€是默認(rèn)值,下次試試)
與services不同,結(jié)構(gòu)體不支持繼承。
2.9 服務(wù)定義(Defining Services)
在流行的序列化/反序列化框架(如protocal buffer)中,Thrift是少有的提供多語(yǔ)言間RPC服務(wù)的框架。這是Thrift的一大特色。
Thrift編譯器會(huì)根據(jù)選擇的目標(biāo)語(yǔ)言為server產(chǎn)生服務(wù)接口代碼,為client產(chǎn)生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:參數(shù)列表的定義與結(jié)構(gòu)體一樣。服務(wù)支持繼承。
慢慢寫(xiě),下次繼續(xù)
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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