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

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

Thrift使用指南

2019-11-11 07:43:27
字體:
來源:轉載
供稿:網友
轉載自:董的博客 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
成人黄色在线观看| 亚洲人成在线一二| 亚洲精品一区二区三区不| 亚洲男人天堂2023| 日韩精品在线免费观看| 精品亚洲一区二区三区四区五区| 国产亚洲欧美日韩一区二区| 97免费视频在线播放| 色婷婷综合成人av| 欧美亚洲国产视频小说| 欧美成人sm免费视频| 欧美中文字幕在线视频| 国产视频福利一区| 原创国产精品91| 菠萝蜜影院一区二区免费| 欧美午夜片在线免费观看| 俺去了亚洲欧美日韩| 欧美精品一二区| 不卡av电影院| 色综合天天综合网国产成人网| 精品久久久久久久久国产字幕| 亚洲香蕉在线观看| 欧美视频专区一二在线观看| 久久这里只有精品99| 日韩成人在线观看| 中文字幕日韩免费视频| 97激碰免费视频| 亚洲欧美日韩视频一区| www.日韩系列| 精品福利视频导航| 在线观看视频99| 91中文字幕在线观看| 久久久久久12| 国产成人免费av电影| 高清欧美性猛交xxxx黑人猛交| 国产成人亚洲综合青青| 九色精品免费永久在线| 97不卡在线视频| 欧洲亚洲女同hd| 成人久久久久久久| 日韩一区视频在线| 黄色成人在线免费| 国产精品伦子伦免费视频| 2019中文字幕在线免费观看| 九九久久久久99精品| 欧美精品18videos性欧美| 韩国福利视频一区| 日韩在线免费视频| 国产精品美女久久久久久免费| 一区二区三区 在线观看视| 欧美激情视频一区二区| 久久久久久久久久久久久久久久久久av| 亚洲精品日韩久久久| 51色欧美片视频在线观看| 精品丝袜一区二区三区| 国产精品免费久久久久影院| 国产成人av在线播放| 国产精品视频精品视频| 久久久亚洲影院| 亚洲一区免费网站| 中文字幕亚洲一区二区三区| 亚洲成人免费在线视频| 黄色成人在线播放| 亚洲аv电影天堂网| 成人性教育视频在线观看| 国产成人精品最新| 久久五月天色综合| 欧美日本在线视频中文字字幕| 久久福利视频导航| 欧洲成人性视频| 久久视频这里只有精品| 精品成人69xx.xyz| 日韩在线播放av| 91精品视频免费看| 一区二区在线免费视频| 最近2019年好看中文字幕视频| 欧美激情一区二区三区高清视频| 亚洲xxx视频| 精品久久久在线观看| 国产精品美女无圣光视频| 国产精品日韩久久久久| 日韩福利在线播放| 久久久久久com| 国产精品一区二区久久久久| 97视频国产在线| 最近中文字幕2019免费| 美女撒尿一区二区三区| 欧美在线视频一区| 亚洲人成在线观看| 美女精品久久久| 成人性生交大片免费观看嘿嘿视频| 国产精品福利无圣光在线一区| 国产欧美日韩免费看aⅴ视频| …久久精品99久久香蕉国产| 人妖精品videosex性欧美| 日韩精品亚洲精品| 91大神在线播放精品| 国产视频丨精品|在线观看| 日韩美女在线看| 欧美日韩aaaa| 国产视频综合在线| 欧美日韩国产中文精品字幕自在自线| 亚洲自拍偷拍网址| 亚洲a中文字幕| 88国产精品欧美一区二区三区| 91麻豆国产语对白在线观看| 在线成人激情视频| 色先锋久久影院av| 成人a视频在线观看| 欧美性videos高清精品| 欧美大学生性色视频| 午夜精品三级视频福利| 亚洲综合国产精品| 色999日韩欧美国产| 欧美视频在线观看 亚洲欧| 欧美中文在线观看国产| 久久天天躁日日躁| 久久综合国产精品台湾中文娱乐网| 伊人久久精品视频| 国产精品高清在线| 亚洲国产成人久久综合一区| 亚洲韩国日本中文字幕| 日韩av影院在线观看| 亚洲色图激情小说| 一区二区三区美女xx视频| 久久综合九色九九| 亚洲欧美一区二区三区久久| 欧美激情亚洲另类| 亚洲色图校园春色| 亚洲一区精品电影| 国产又爽又黄的激情精品视频| 欧美国产精品va在线观看| 欧美丰满老妇厨房牲生活| 欧美精品在线看| 日韩欧美精品免费在线| 成人国产精品久久久久久亚洲| 国内精品视频在线| 亚洲精品视频中文字幕| 久久精视频免费在线久久完整在线看| 亚洲福利视频专区| 久久久国产成人精品| 91国内免费在线视频| 91视频-88av| 国产有码在线一区二区视频| 国产精品视频网| 亚洲国产天堂网精品网站| 欧美日韩视频在线| www.久久草.com| 欧美老肥婆性猛交视频| 浅井舞香一区二区| 久99九色视频在线观看| 精品久久久久久中文字幕大豆网| 欧美一性一乱一交一视频| 精品国偷自产在线视频99| 亚洲欧美制服另类日韩| 亚洲精品中文字| 亚洲精品国产精品自产a区红杏吧| 精品毛片三在线观看| 亚洲区中文字幕| 欧美成人午夜视频| 欧美亚洲成人免费| 日韩精品久久久久久久玫瑰园| 欧洲日本亚洲国产区| 久久色免费在线视频|