thrift是一套遠程調用框架最铁,最初是由Facebook開發(fā)的肌似,并在2008年捐給了Apache基金會费就,成為了一個孵化器項目。thrift支持可擴展且跨語言的服務的開發(fā)川队,它結合了功能強大的軟件堆棧和代碼生成引擎力细,支持的客戶端語言包括C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 。
Thrift的設計提供了以下這些特性:
1固额、語言無關的類型
因為類型是使用定義文件按照語言中立的方式規(guī)定的眠蚂,所以它們可以被不同的語言分析。比如斗躏,C++的結構可以和Python的字典類型相互交換數(shù)據(jù)逝慧。
2、通用傳輸接口
不論你使用的是磁盤文件瑟捣、內(nèi)存數(shù)據(jù)還是socket流,都可以使用同一段應用代碼栅干。
3迈套、協(xié)議無關
Thrift會對數(shù)據(jù)類型進行編碼和解碼,可以跨協(xié)議使用碱鳞。
4桑李、支持版本
數(shù)據(jù)類型可以加入版本信息,來支持客戶端API的更新窿给。
thrift安裝
對于mac用戶來說贵白,brew是個很好用的命令,使用命令快速安裝thrift崩泡。
admindeMacBook-Pro-5:~ hzjdemac$ brew install thrift
==> Installing dependencies for thrift: boost
==> Installing thrift dependency: boost
==> Downloading https://homebrew.bintray.com/bottles/boost-1.68.0.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring boost-1.68.0.high_sierra.bottle.tar.gz
?? /usr/local/Cellar/boost/1.68.0: 13,712 files, 460.2MB
==> Installing thrift
==> Downloading https://homebrew.bintray.com/bottles/thrift-0.11.0.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring thrift-0.11.0.high_sierra.bottle.tar.gz
==> Caveats
To install Ruby binding:
gem install thrift
==> Summary
?? /usr/local/Cellar/thrift/0.11.0: 102 files, 7MB
==> Caveats
==> thrift
To install Ruby binding:
gem install thrift
admindeMacBook-Pro-5:~ hzjdemac$ thrift
Usage: thrift [options] file
Use thrift -help for a list of options
admindeMacBook-Pro-5:~ hzjdemac$ thrift -version
Thrift version 0.11.0
數(shù)據(jù)類型
java中定義一個接口需要傳入?yún)?shù)禁荒,方法名,返回值和拋異常操作角撞,這其中比較關鍵的是參數(shù)呛伴。thrift自己內(nèi)部有一套與語言無關的類型勃痴,可以與java中的類型進行對應,將java中的類型換成thrift對應的類型就能夠將java接口定義轉換成thrift接口定義热康。
類型 | 解釋 | java對應類型 | C++對應類型 |
---|---|---|---|
bool | 布爾值沛申,true 或 false | boolean | bool |
byte | 8 位有符號整數(shù) | byte | int |
i16 | 16 位有符號整數(shù) | short | int |
i32 | 32 位有符號整數(shù) | int | int |
i64 | 64 位有符號整數(shù) | long | long |
double | 64 位浮點數(shù) | double | double |
string | utf-8編碼的字符串 | String | string |
list<t> | 元素類型為t的有序表,容許元素重復 | ArrayList | vector |
set<t> | 元素類型為t的無序表姐军,不容許元素重復 | HashSet | set |
map<k,t> | 鍵類型為t铁材,值類型為t的kv對,鍵不容許重復 | HashMap | map |
struct | 一組對象 | class | struct |
exception | 異常 | Exception | Exception |
service | 服務類型 | interface | 抽象類 |
enum | 枚舉 | enum | enum |
namespace:熟悉C++的朋友肯定知道奕锌,提供了一種組織(隔離)代碼的簡便方式著觉,類似于C++中的namespace和JAVA中的package。
include:包含其它thrift文件歇攻,功能類似于C++中的include和JAVA中的import固惯。
thrift中struct是定義為一種對象,和面向對象語言的class差不多.,但是struct有以下一些約束:
struct不能繼承缴守,但是可以嵌套葬毫,不能嵌套自己。
其成員都是有明確類型
成員是被正整數(shù)編號過的屡穗,其中的編號使不能重復的贴捡,這個是為了在傳輸過程中編碼使用。
成員分割符可以是逗號(,)或是分號(;)村砂,而且可以混用烂斋,但是為了清晰期間,建議在定義中只使用一種础废,比如C++學習者可以就使用分號(;)汛骂。
字段會有optional和required之分和protobuf一樣,但是如果不指定則為無類型—可以不填充該值评腺,但是在序列化傳輸?shù)臅r候也會序列化進去帘瞭,optional是不填充則部序列化,required是必須填充也必須序列化蒿讥。
每個字段可以設置默認值
同一文件可以定義多個struct蝶念,也可以定義在不同的文件,進行include引入芋绸。
下面將舉一個例子媒殉,該例子用thrift定義了一個接口,基本囊括了類型定義和方法定義的基本用法摔敛。
樣例
enum EnOpType {
CMD_OK = 0, // (0)
CMD_NOT_EXIT = 2000, // (2000)
CMD_EXIT = 2001, // (2001)
CMD_ADD = 2002 // (2002)
}
struct UserProfile {
1: i32 uid = 1,
2: string name = "User1",
3: string blurb
}
include "UserProfile.thrift"
include "EnOpType.thrift"
struct Node {
1: i32 id,
2: string name,
3: EnOpType.EnOpType enOpType;
4: list<UserProfile.UserProfile> subNodeList
}
exception CommonException {
1: i32 errorCode,
2: string message
}
include "Node.thrift"
include "UserProfile.thrift"
include "exception.thrift"
service UserStorage {
void store(1:UserProfile.UserProfile user) throws (1:exception.CommonException commonException);
Node.Node retrieve(1:i32 uid) throws (1:exception.CommonException commonException);
}
最后對每個文件使用thrift命令生成指定語言的文件, 使用ls可以查看到所有的文件廷蓉,打開UserStorage.java文件,可以清楚得看到生成的java接口马昙。
admindeMacBook-Pro-5:~ hzjdemac$ thrift -r -gen java UserStorage.thrift
admindeMacBook-Pro-5:~ hzjdemac$ cd gen-java
admindeMacBook-Pro-5:gen-java hzjdemac$ ls
CommonException.java EnOpType.thrift Node.thrift UserProfile.thrift UserStorage.thrift model.thrift
EnOpType.java Node.java UserProfile.java UserStorage.java exception.thrift
admindeMacBook-Pro-5:gen-java hzjdemac$ vim UserStorage.java
/**
* Autogenerated by Thrift Compiler (0.11.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.11.0)", date = "2018-11-25")
public class UserStorage {
public interface Iface {
public void store(UserProfile user) throws CommonException, org.apache.thrift.TException;
public Node retrieve(int uid) throws CommonException, org.apache.thrift.TException;
}
public interface AsyncIface {
public void store(UserProfile user, org.apache.thrift.async.AsyncMethodCallback<Void> resultHandler) throws org.apache.thrift.TException;
public void retrieve(int uid, org.apache.thrift.async.AsyncMethodCallback<Node> resultHandler) throws org.apache.thrift.TException;
}
public static class Client extends org.apache.thrift.TServiceClient implements Iface {
public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
public Factory() {}
public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
return new Client(prot);
}
public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
return new Client(iprot, oprot);
}
}
public Client(org.apache.thrift.protocol.TProtocol prot)
{
super(prot, prot);
}
public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
super(iprot, oprot);
}
public void store(UserProfile user) throws CommonException, org.apache.thrift.TException
{
send_store(user);
recv_store();
}
好了苦酱,本節(jié)主要講解了如何將一個定義thrift service售貌,生成了java中的接口,很可惜的地方是不支持泛型疫萤。下篇將講解客戶端和服務端的rpc通信颂跨。
參考資料:
1.https://www.cnblogs.com/duanxz/p/5516558.html
2.https://www.cnblogs.com/valor-xh/p/6386584.html