国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Thrift使用指南

2019-11-11 05:44:57
字體:
供稿:網(wǎng)友
轉(zhuǎn)載自:董的博客 http://dongxicheng.org/search-engine/thrift-guide/

1. 內(nèi)容概要

本文檔比較全面的介紹了thrift語法,代碼生成結(jié)構(gòu)和應(yīng)用經(jīng)驗(yàn)。本文主要講述的對(duì)象是thrift文件,并未涉及其client和server的編寫方法。

2. 語法參考

2.1 Types

Thrift類型系統(tǒng)包括預(yù)定義基本類型,用戶自定義結(jié)構(gòu)體,容器類型,異常和服務(wù)定義

(1) 基本類型

12345678910111213

bool:布爾類型(trueor value),占一個(gè)字節(jié) byte:有符號(hào)字節(jié) i16:16位有符號(hào)整型 i32:32位有符號(hào)整型 i64:64位有符號(hào)整型 double:64位浮點(diǎn)數(shù) string:未知編碼或者二進(jìn)制的字符串

注意,thrift不支持無符號(hào)整型,因?yàn)楹芏嗄繕?biāo)語言不存在無符號(hào)整型(如java)。

(2) 容器類型

Thrift容器與類型密切相關(guān),它與當(dāng)前流行編程語言提供的容器類型相對(duì)應(yīng),采用java泛型風(fēng)格表示的。Thrift提供了3種容器類型:

List<t1>:一系列t1類型的元素組成的有序表,元素可以重復(fù)

Set<t1>:一系列t1類型的元素組成的無序表,元素唯一

Map<t1,t2>:key/value對(duì)(key的類型是t1且key唯一,value類型是t2)。

容器中的元素類型可以是除了service以外的任何合法thrift類型(包括結(jié)構(gòu)體和異常)。

(3)  結(jié)構(gòu)體和異常

Thrift結(jié)構(gòu)體在概念上同C語言結(jié)構(gòu)體類型—— 一種將相關(guān)屬性聚集(封裝)在一起的方式。在面向?qū)ο笳Z言中,thrift結(jié)構(gòu)體被轉(zhuǎn)換成類。

異常在語法和功能上類似于結(jié)構(gòu)體,只不過異常使用關(guān)鍵字exception而不是struct關(guān)鍵字聲明。但它在語義上不同于結(jié)構(gòu)體——當(dāng)定義一個(gè)RPC服務(wù)時(shí),開發(fā)者可能需要聲明一個(gè)遠(yuǎn)程方法拋出一個(gè)異常。

結(jié)構(gòu)體和異常的聲明將在下一節(jié)介紹。

(4)  服務(wù)

服務(wù)的定義方法在語法上等同于面向?qū)ο笳Z言中定義接口。Thrift編譯器會(huì)產(chǎn)生實(shí)現(xiàn)這些接口的client和server樁。具體參見下一節(jié)。

(5)  類型定義

Thrift支持C/C++風(fēng)格的typedef:

123

typedefi32 MyInteger   //a typedefTweet ReTweet  //b

說明:

a.  末尾沒有逗號(hào)

b.   struct可以使用typedef

2.2   枚舉類型

可以像C/C++那樣定義枚舉類型,如:

123456789101112131415161718192021222324252627

enumTweetType { TWEET,      //a RETWEET = 2, //b DM = 0xa,  //c REPLY }       //d structTweet { 1: required i32 userId; 2: required string userName; 3: required string text; 4: optional Location loc; 5: optional TweetType tweetType = TweetType.TWEET // e 16: optional string language = "english" }

說明:

a.  編譯器默認(rèn)從0開始賦值

b.  可以賦予某個(gè)常量某個(gè)整數(shù)

c.  允許常量是十六進(jìn)制整數(shù)

d.  末尾沒有逗號(hào)

e.  給常量賦缺省值時(shí),使用常量的全稱

注意,不同于PRotocol buffer,thrift不支持枚舉類嵌套,枚舉常量必須是32位的正整數(shù)

2.3   注釋

Thrfit支持shell注釋風(fēng)格,C/C++語言中單行或者多行注釋風(fēng)格

1234567891011

# 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.4   命名空間

Thrift中的命名空間同C++中的namespace和java中的package類似,它們均提供了一種組織(隔離)代碼的方式。因?yàn)槊糠N語言均有自己的命名空間定義方式(如python中有module),thrift允許開發(fā)者針對(duì)特定語言定義namespace:

123

namespacecpp com.example.project  // a namespacejava com.example.project // b

說明:

a.  轉(zhuǎn)化成namespace com { namespace example { namespace project {

b.  轉(zhuǎn)換成package com.example.project

2.5   文件包含

Thrift允許thrift文件包含,用戶需要使用thrift文件名作為前綴訪問被包含的對(duì)象,如:

123456789

include"tweet.thrift"          // a ... structTweetSearchResult { 1: list<tweet.Tweet> tweets; // b }

說明:

a.  thrift文件名要用雙引號(hào)包含,末尾沒有逗號(hào)或者分號(hào)

b.  注意tweet前綴

2.6   常量

Thrift允許用戶定義常量,復(fù)雜的類型和結(jié)構(gòu)體可使用JSON形式表示。

123

consti32 INT_CONST = 1234;    // a constmap<string,string> MAP_CONST = {"hello":"world","goodnight":"moon"}

說明:

a.  分號(hào)是可選的,可有可無;支持十六進(jìn)制賦值。

2.7   定義結(jié)構(gòu)體

結(jié)構(gòu)體由一系列域組成,每個(gè)域有唯一整數(shù)標(biāo)識(shí)符,類型,名字和可選的缺省參數(shù)組成。如:

123456789101112131415161718192021

structTweet { 1: required i32 userId;                  // a 2: required string userName;             // b 3: required string text; 4: optional Location loc;                // c 16: optional string language = "english"// d } structLocation {                            // e 1: required doublelatitude; 2: required doublelongitude; }

說明:

a.  每個(gè)域有一個(gè)唯一的,正整數(shù)標(biāo)識(shí)符

b.  每個(gè)域可以標(biāo)識(shí)為required或者optional(也可以不注明)

c.  結(jié)構(gòu)體可以包含其他結(jié)構(gòu)體

d.  域可以有缺省值

e.  一個(gè)thrift中可定義多個(gè)結(jié)構(gòu)體,并存在引用關(guān)系

規(guī)范的struct定義中的每個(gè)域均會(huì)使用required或者optional關(guān)鍵字進(jìn)行標(biāo)識(shí)。如果required標(biāo)識(shí)的域沒有賦值,thrift將給予提示。如果optional標(biāo)識(shí)的域沒有賦值,該域?qū)⒉粫?huì)被序列化傳輸。如果某個(gè)optional標(biāo)識(shí)域有缺省值而用戶沒有重新賦值,則該域的值一直為缺省值。

與service不同,結(jié)構(gòu)體不支持繼承,即,一個(gè)結(jié)構(gòu)體不能繼承另一個(gè)結(jié)構(gòu)體。

2.8   定義服務(wù)

在流行的序列化/反序列化框架(如protocol buffer)中,thrift是少有的提供多語言間RPC服務(wù)的框架。

Thrift編譯器會(huì)根據(jù)選擇的目標(biāo)語言為server產(chǎn)生服務(wù)接口代碼,為client產(chǎn)生樁代碼。

1234567891011121314151617181920

//“Twitter”與“{”之間需要有空格!!!service Twitter { // 方法定義方式類似于C語言中的方式,它有一個(gè)返回值,一系列參數(shù)和可選的異常 // 列表. 注意,參數(shù)列表和異常列表定義方式與結(jié)構(gòu)體中域定義方式一致. voidping(),                                   // a boolpostTweet(1:Tweet tweet);                  // b TweetSearchResult searchTweets(1:string query); // c // ”oneway”標(biāo)識(shí)符表示client發(fā)出請(qǐng)求后不必等待回復(fù)(非阻塞)直接進(jìn)行下面的操作, // ”oneway”方法的返回值必須是void onewayvoidzip()                              // d }

說明:

a. 函數(shù)定義可以使用逗號(hào)或者分號(hào)標(biāo)識(shí)結(jié)束

b. 參數(shù)可以是基本類型或者結(jié)構(gòu)體,參數(shù)是只讀的(const),不可以作為返回值!!!

c. 返回值可以是基本類型或者結(jié)構(gòu)體

d. 返回值可以是void

注意,函數(shù)中參數(shù)列表的定義方式與struct完全一樣

Service支持繼承,一個(gè)service可使用extends關(guān)鍵字繼承另一個(gè)service

3.  產(chǎn)生代碼

本節(jié)介紹thrift產(chǎn)生各種目標(biāo)語言代碼的方式。本節(jié)從幾個(gè)基本概念開始,逐步引導(dǎo)開發(fā)者了解產(chǎn)生的代碼是怎么樣組織的,進(jìn)而幫助開發(fā)者更快地明白thrift的使用方法。

概念

Thrift的網(wǎng)絡(luò)棧如下所示:

3.1   Transport

Transport層提供了一個(gè)簡單的網(wǎng)絡(luò)讀寫抽象層。這使得thrift底層的transport從系統(tǒng)其它部分(如:序列化/反序列化)解耦。以下是一些Transport接口提供的方法:

123456789

open close read write flush

除了以上幾個(gè)接口,Thrift使用ServerTransport接口接受或者創(chuàng)建原始transport對(duì)象。正如名字暗示的那樣,ServerTransport用在server端,為到來的連接創(chuàng)建Transport對(duì)象。

1234567

open listen accept close

3.2   Protocol

Protocol抽象層定義了一種將內(nèi)存中數(shù)據(jù)結(jié)構(gòu)映射成可傳輸格式的機(jī)制。換句話說,Protocol定義了datatype怎樣使用底層的Transport對(duì)自己進(jìn)行編解碼。因此,Protocol的實(shí)現(xiàn)要給出編碼機(jī)制并負(fù)責(zé)對(duì)數(shù)據(jù)進(jìn)行序列化。

Protocol接口的定義如下:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677

writeMessageBegin(name, type, seq) writeMessageEnd() writeStructBegin(name) writeStructEnd() writeFieldBegin(name, type, id) writeFieldEnd() writeFieldStop() writeMapBegin(ktype, vtype, size) writeMapEnd() writeListBegin(etype, size) writeListEnd() writeSetBegin(etype, size) writeSetEnd() writeBool(bool) writeByte(byte) writeI16(i16) writeI32(i32) writeI64(i64) writeDouble(double) writeString(string) name, type, seq = readMessageBegin() readMessageEnd() name = readStructBegin() readStructEnd() name, type, id = readFieldBegin() readFieldEnd() k, v, size = readMapBegin() readMapEnd() etype, size = readListBegin() readListEnd() etype, size = readSetBegin() readSetEnd() bool= readBool() byte = readByte() i16 = readI16() i32 = readI32() i64 = readI64() double= readDouble() string = readString()

下面是一些對(duì)大部分thrift支持的語言均可用的protocol:

(1)     binary:簡單的二進(jìn)制編碼

(2)     Compact

(3)     Json

3.3   Processor

Processor封裝了從輸入數(shù)據(jù)流中讀數(shù)據(jù)和向數(shù)據(jù)數(shù)據(jù)流中寫數(shù)據(jù)的操作。讀寫數(shù)據(jù)流用Protocol對(duì)象表示。Processor的結(jié)構(gòu)體非常簡單:

12345

interface TProcessor { boolprocess(TProtocol in, TProtocol out) throws TException }

與服務(wù)相關(guān)的processor實(shí)現(xiàn)由編譯器產(chǎn)生。Processor主要工作流程如下:從連接中讀取數(shù)據(jù)(使用輸入protocol),將處理授權(quán)給handler(由用戶實(shí)現(xiàn)),最后將結(jié)果寫到連接上(使用輸出protocol)。

3.4   Server

Server將以上所有特性集成在一起:

(1)  創(chuàng)建一個(gè)transport對(duì)象

(2)  為transport對(duì)象創(chuàng)建輸入輸出protocol

(3)  基于輸入輸出protocol創(chuàng)建processor

(4)  等待連接請(qǐng)求并將之交給processor處理

3.5   應(yīng)用舉例

下面,我們討論thrift文件產(chǎn)生的特定語言代碼。下面給出thrift文件描述:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061

namespacecpp thrift.example namespacejava thrift.example enumTweetType { TWEET, RETWEET = 2, DM = 0xa, REPLY } structLocation { 1: required doublelatitude; 2: required doublelongitude; } structTweet { 1: required i32 userId; 2: required string userName; 3: required string text; 4: optional Location loc; 5: optional TweetType tweetType = TweetType.TWEET; 16: optional string language = "english"; } typedeflist<Tweet> TweetList structTweetSearchResult { 1: TweetList tweets; } consti32 MAX_RESULTS = 100; service Twitter { voidping(), boolpostTweet(1:Tweet tweet); TweetSearchResult searchTweets(1:string query); onewayvoidzip() }

(1) Java語言

(a)  產(chǎn)生的文件

一個(gè)單獨(dú)的文件(Constants.java)包含所有的常量定義。

每個(gè)結(jié)構(gòu)體,枚舉或者服務(wù)各占一個(gè)文件

$ tree gen-java

`– thrift

`– example

|– Constants.java

|– Location.java

|– Tweet.java

|– TweetSearchResult.java

|– TweetType.java

`– Twitter.java

(b)  類型

thrift將各種基本類型和容器類型映射成java類型:

12345678910111213141516171819bool: boolean byte: byte i16:short i32:int i64:long double:double string: String list<t1>: List<t1> set<t1>: Set<t1> map<t1,t2>: Map<t1, t2>

(c)  typedef

Java不支持typedef,它只使用原始類型,如,在上面的例子中,產(chǎn)生的代碼中,TweetSearchResult會(huì)被還原成list<Tweet> tweets

(d)  Enum

Thrift直接將枚舉類型映射成java的枚舉類型。用戶可以使用geValue方法獲取枚舉常量的值。此外,編譯器會(huì)產(chǎn)生一個(gè)findByValue方法獲取枚舉對(duì)應(yīng)的數(shù)值。

(e)  常量

Thrift把所有的常量放在一個(gè)叫Constants的public類中,每個(gè)常量修飾符是public static final。

(2)  C++語言

(a)  產(chǎn)生的文件

所有變量均存放在一個(gè).cpp/.h文件對(duì)中

所有的類型定義(枚舉或者結(jié)構(gòu)體)存放到另一個(gè).cpp/.h文件對(duì)中

每一個(gè)service有自己的.cpp/.h文件

$ tree gen-cpp

|– example_constants.cpp

|– example_constants.h

|– example_types.cpp

|– example_types.h

|– Twitter.cpp

|– Twitter.h

`– Twitter_server.skeleton.cpp

其他語言

Python,Ruby,Javascript

4.  實(shí)踐經(jīng)驗(yàn)

thrift文件內(nèi)容可能會(huì)隨著時(shí)間變化的。如果已經(jīng)存在的消息類型不再符合設(shè)計(jì)要求,比如,新的設(shè)計(jì)要在message格式中添加一個(gè)額外字段,但你仍想使用以前的thrift文件產(chǎn)生的處理代碼。如果想要達(dá)到這個(gè)目的,只需:

(1)  不要修改已存在域的整數(shù)編號(hào)

(2)  新添加的域必須是optional的,以便格式兼容。對(duì)于一些語言,如果要為optional的字段賦值,需要特殊處理,比如對(duì)于C++語言,要為

123456789

structExample{ 1 : i32 id, 2 : string name, 3 : optional age, }

中的optional字段age賦值,需要將它的__isset值設(shè)為true,這樣才能序列化并傳輸或者存儲(chǔ)(不然optional字段被認(rèn)為不存在,不會(huì)被傳輸或者存儲(chǔ)),

如:

123456789

Example example; ...... example.age=10, example.__isset.age = true;//__isset是每個(gè)thrift對(duì)象的自帶的public成員,來指定optional字段是否啟用并賦值。 ......

(3)  非required域可以刪除,前提是它的整數(shù)編號(hào)不會(huì)被其他域使用。對(duì)于刪除的字段,名字前面可添加“OBSOLETE_”以防止其他字段使用它的整數(shù)編號(hào)。

(4) thrift文件應(yīng)該是unix格式的(windows下的換行符與unix不同,可能會(huì)導(dǎo)致你的程序編譯不過),如果是在window下編寫的,可使用dos2unix轉(zhuǎn)化為unix格式。

(5)  貌似當(dāng)前的thrift版本(0.6.1)不支持常量表達(dá)式的定義(如 const i32 DAY = 24 * 60 * 60),這可能是考慮到不同語言,運(yùn)算符不盡相同。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 明水县| 肃北| 定安县| 错那县| 建昌县| 丹江口市| 南宁市| 昌吉市| 西乡县| 克拉玛依市| 嘉祥县| 鱼台县| 丘北县| 平塘县| 宜都市| 淄博市| 集贤县| 阿克陶县| 阿图什市| 宜黄县| 图木舒克市| 荔浦县| 商水县| 陇西县| 霞浦县| 新晃| 永丰县| 卓尼县| 民权县| 河东区| 赣州市| 凤山县| 图木舒克市| 汉寿县| 开远市| 宣恩县| 新疆| 郧西县| 德州市| 图们市| 广西|