亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Thrift使用指南

2019-11-11 05:44:57
字體:
來源:轉載
供稿:網友
轉載自:董的博客 http://dongxicheng.org/search-engine/thrift-guide/

1. 內容概要

本文檔比較全面的介紹了thrift語法,代碼生成結構和應用經驗。本文主要講述的對象是thrift文件,并未涉及其client和server的編寫方法。

2. 語法參考

2.1 Types

Thrift類型系統包括預定義基本類型,用戶自定義結構體,容器類型,異常和服務定義

(1) 基本類型

12345678910111213

bool:布爾類型(trueor value),占一個字節 byte:有符號字節 i16:16位有符號整型 i32:32位有符號整型 i64:64位有符號整型 double:64位浮點數 string:未知編碼或者二進制的字符串

注意,thrift不支持無符號整型,因為很多目標語言不存在無符號整型(如java)。

(2) 容器類型

Thrift容器與類型密切相關,它與當前流行編程語言提供的容器類型相對應,采用java泛型風格表示的。Thrift提供了3種容器類型:

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

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

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

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

(3)  結構體和異常

Thrift結構體在概念上同C語言結構體類型—— 一種將相關屬性聚集(封裝)在一起的方式。在面向對象語言中,thrift結構體被轉換成類。

異常在語法和功能上類似于結構體,只不過異常使用關鍵字exception而不是struct關鍵字聲明。但它在語義上不同于結構體——當定義一個RPC服務時,開發者可能需要聲明一個遠程方法拋出一個異常。

結構體和異常的聲明將在下一節介紹。

(4)  服務

服務的定義方法在語法上等同于面向對象語言中定義接口。Thrift編譯器會產生實現這些接口的client和server樁。具體參見下一節。

(5)  類型定義

Thrift支持C/C++風格的typedef:

123

typedefi32 MyInteger   //a typedefTweet ReTweet  //b

說明:

a.  末尾沒有逗號

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.  編譯器默認從0開始賦值

b.  可以賦予某個常量某個整數

c.  允許常量是十六進制整數

d.  末尾沒有逗號

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

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

2.3   注釋

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

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類似,它們均提供了一種組織(隔離)代碼的方式。因為每種語言均有自己的命名空間定義方式(如python中有module),thrift允許開發者針對特定語言定義namespace:

123

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

說明:

a.  轉化成namespace com { namespace example { namespace project {

b.  轉換成package com.example.project

2.5   文件包含

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

123456789

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

說明:

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

b.  注意tweet前綴

2.6   常量

Thrift允許用戶定義常量,復雜的類型和結構體可使用JSON形式表示。

123

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

說明:

a.  分號是可選的,可有可無;支持十六進制賦值。

2.7   定義結構體

結構體由一系列域組成,每個域有唯一整數標識符,類型,名字和可選的缺省參數組成。如:

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.  每個域有一個唯一的,正整數標識符

b.  每個域可以標識為required或者optional(也可以不注明)

c.  結構體可以包含其他結構體

d.  域可以有缺省值

e.  一個thrift中可定義多個結構體,并存在引用關系

規范的struct定義中的每個域均會使用required或者optional關鍵字進行標識。如果required標識的域沒有賦值,thrift將給予提示。如果optional標識的域沒有賦值,該域將不會被序列化傳輸。如果某個optional標識域有缺省值而用戶沒有重新賦值,則該域的值一直為缺省值。

與service不同,結構體不支持繼承,即,一個結構體不能繼承另一個結構體。

2.8   定義服務

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

Thrift編譯器會根據選擇的目標語言為server產生服務接口代碼,為client產生樁代碼。

1234567891011121314151617181920

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

說明:

a. 函數定義可以使用逗號或者分號標識結束

b. 參數可以是基本類型或者結構體,參數是只讀的(const),不可以作為返回值?。?!

c. 返回值可以是基本類型或者結構體

d. 返回值可以是void

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

Service支持繼承,一個service可使用extends關鍵字繼承另一個service

3.  產生代碼

本節介紹thrift產生各種目標語言代碼的方式。本節從幾個基本概念開始,逐步引導開發者了解產生的代碼是怎么樣組織的,進而幫助開發者更快地明白thrift的使用方法。

概念

Thrift的網絡棧如下所示:

3.1   Transport

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

123456789

open close read write flush

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

1234567

open listen accept close

3.2   Protocol

Protocol抽象層定義了一種將內存中數據結構映射成可傳輸格式的機制。換句話說,Protocol定義了datatype怎樣使用底層的Transport對自己進行編解碼。因此,Protocol的實現要給出編碼機制并負責對數據進行序列化。

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()

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

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

(2)     Compact

(3)     Json

3.3   Processor

Processor封裝了從輸入數據流中讀數據和向數據數據流中寫數據的操作。讀寫數據流用Protocol對象表示。Processor的結構體非常簡單:

12345

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

與服務相關的processor實現由編譯器產生。Processor主要工作流程如下:從連接中讀取數據(使用輸入protocol),將處理授權給handler(由用戶實現),最后將結果寫到連接上(使用輸出protocol)。

3.4   Server

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

(1)  創建一個transport對象

(2)  為transport對象創建輸入輸出protocol

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

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

3.5   應用舉例

下面,我們討論thrift文件產生的特定語言代碼。下面給出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)  產生的文件

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

每個結構體,枚舉或者服務各占一個文件

$ 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,它只使用原始類型,如,在上面的例子中,產生的代碼中,TweetSearchResult會被還原成list<Tweet> tweets

(d)  Enum

Thrift直接將枚舉類型映射成java的枚舉類型。用戶可以使用geValue方法獲取枚舉常量的值。此外,編譯器會產生一個findByValue方法獲取枚舉對應的數值。

(e)  常量

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

(2)  C++語言

(a)  產生的文件

所有變量均存放在一個.cpp/.h文件對中

所有的類型定義(枚舉或者結構體)存放到另一個.cpp/.h文件對中

每一個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.  實踐經驗

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

(1)  不要修改已存在域的整數編號

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

123456789

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

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

如:

123456789

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

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

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

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲日韩第一页| 国产日韩在线一区| 亚洲免费一级电影| 成人久久久久久久| 久久成人综合视频| 国产美女扒开尿口久久久| 综合av色偷偷网| 中文字幕在线日韩| 91九色单男在线观看| 最近免费中文字幕视频2019| 国产欧美精品久久久| 久久五月天综合| 国语自产精品视频在线看一大j8| 国产精品久久综合av爱欲tv| 亚洲欧美国产精品久久久久久久| 久久天天躁狠狠躁夜夜爽蜜月| 久久精品中文字幕| 永久免费毛片在线播放不卡| 日韩av电影国产| 国产va免费精品高清在线| 日韩成人在线视频观看| 日韩综合视频在线观看| 91国产中文字幕| 久久久免费精品视频| 国产精品三级美女白浆呻吟| 国产精品69精品一区二区三区| 国产91精品视频在线观看| 亚洲自拍中文字幕| 国产精品pans私拍| 日本久久久久久| 欧美老肥婆性猛交视频| 欧美中文字幕在线视频| 欧美一级淫片丝袜脚交| 欧洲亚洲在线视频| 国产精品日韩久久久久| 久久影视三级福利片| 青青久久av北条麻妃黑人| 亚洲自拍偷拍福利| 色综合亚洲精品激情狠狠| 欧美在线视频在线播放完整版免费观看| 九九热这里只有精品免费看| 国产精品露脸自拍| 伊人久久久久久久久久久| 在线观看久久av| 91日韩在线视频| 亚洲人成电影在线观看天堂色| 亚洲激情在线观看| 成人久久18免费网站图片| 97国产精品久久| 欧美激情手机在线视频| 亚洲自拍小视频免费观看| 日韩中文在线视频| 日韩www在线| 久久频这里精品99香蕉| 日韩在线视频线视频免费网站| 一区二区三区日韩在线| 国产精品久久久久久久午夜| 国产精品最新在线观看| 亚洲免费视频网站| 国产精品aaaa| 国产一区二区欧美日韩| 国产一区二区三区在线看| 亚州欧美日韩中文视频| 国产午夜精品一区二区三区| 国产精品视频xxx| 亚洲最新av网址| 亚洲精品电影在线| 国产综合久久久久久| 国产丝袜精品第一页| 在线免费观看羞羞视频一区二区| 久久福利视频导航| 欧美高清理论片| 精品久久久久国产| 国产精品视频99| 中文字幕国产亚洲| 久久久亚洲欧洲日产国码aⅴ| 日韩av在线资源| 成人黄色片网站| 欧美裸体xxxx极品少妇| 黄色成人av在线| 久久久久久久久久久人体| 欧美日韩国产综合新一区| 夜夜狂射影院欧美极品| 日韩中文字幕免费| 欧美成人中文字幕在线| 国产精品嫩草影院一区二区| 国产一区av在线| 日韩毛片在线看| 91精品国产综合久久久久久久久| 精品亚洲国产成av人片传媒| 91精品国产免费久久久久久| 欧美老女人性视频| 清纯唯美日韩制服另类| 亚洲精美色品网站| 中文在线资源观看视频网站免费不卡| 国产香蕉一区二区三区在线视频| 日韩视频一区在线| 成人国产精品色哟哟| 欧美巨乳在线观看| 成人网欧美在线视频| 久久艳片www.17c.com| 久久精品夜夜夜夜夜久久| 麻豆国产精品va在线观看不卡| 欧美精品videosex牲欧美| 欧美激情在线有限公司| 福利一区福利二区微拍刺激| 日韩av免费在线观看| 狠狠色噜噜狠狠狠狠97| 国色天香2019中文字幕在线观看| 91av在线看| 久久69精品久久久久久久电影好| 亚洲成人激情视频| 国产欧美最新羞羞视频在线观看| 欧美国产日韩二区| 亚洲国产精品中文| 亚洲伊人久久大香线蕉av| 伊人男人综合视频网| 国产成人精品免费视频| 亚洲肉体裸体xxxx137| 国产成人啪精品视频免费网| 在线丨暗呦小u女国产精品| 亚洲专区国产精品| 日韩av在线免费播放| 欧美精品www在线观看| 姬川优奈aav一区二区| 欧美视频裸体精品| 欧美在线欧美在线| 欧美在线观看www| 亚洲白拍色综合图区| 欧美在线视频免费| 激情亚洲一区二区三区四区| 久久久久久久久久久av| 7m精品福利视频导航| 久久福利网址导航| 成人国产精品日本在线| 国产精品久久久久99| 亚洲高清一区二| 91久久精品久久国产性色也91| 欧美xxxx18性欧美| 中文字幕亚洲欧美日韩在线不卡| 亚洲色图激情小说| 欧美一级片久久久久久久| 97超碰色婷婷| 国产亚洲综合久久| 日韩av中文字幕在线| 热久久这里只有精品| 久久国产精彩视频| 亚洲欧美一区二区三区情侣bbw| 91免费版网站入口| 色爱av美腿丝袜综合粉嫩av| 欧美精品videosex极品1| 亚洲男人天堂手机在线| 亚洲国产精品久久| 欧美与黑人午夜性猛交久久久| 韩国欧美亚洲国产| 亚洲最大福利网| 久久精品国产69国产精品亚洲| 欧美亚洲成人xxx| 国产精品自产拍在线观| 精品国内自产拍在线观看| 九九久久国产精品| 性欧美在线看片a免费观看| 亚洲福利视频免费观看| 国产性猛交xxxx免费看久久|