thrift教程之接口定义

thrift是一套远程调用框架,最初是由Facebook开发的,并在2008年捐给了Apache基金会,成为了一个孵化器项目。thrift支持可扩展且跨语言的服务的开发,它结合了功能强大的软件堆栈和代码生成引擎,支持的客户端语言包括C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 。
Thrift的设计提供了以下这些特性:
1、语言无关的类型
因为类型是使用定义文件按照语言中立的方式规定的,所以它们可以被不同的语言分析。比如,C++的结构可以和Python的字典类型相互交换数据。
2、通用传输接口
不论你使用的是磁盘文件、内存数据还是socket流,都可以使用同一段应用代码。
3、协议无关
Thrift会对数据类型进行编码和解码,可以跨协议使用。
4、支持版本
数据类型可以加入版本信息,来支持客户端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

数据类型

java中定义一个接口需要传入参数,方法名,返回值和抛异常操作,这其中比较关键的是参数。thrift自己内部有一套与语言无关的类型,可以与java中的类型进行对应,将java中的类型换成thrift对应的类型就能够将java接口定义转换成thrift接口定义。

类型 解释 java对应类型 C++对应类型
bool 布尔值,true 或 false boolean bool
byte 8 位有符号整数 byte int
i16 16 位有符号整数 short int
i32 32 位有符号整数 int int
i64 64 位有符号整数 long long
double 64 位浮点数 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不能继承,但是可以嵌套,不能嵌套自己。
其成员都是有明确类型
成员是被正整数编号过的,其中的编号使不能重复的,这个是为了在传输过程中编码使用。
成员分割符可以是逗号(,)或是分号(;),而且可以混用,但是为了清晰期间,建议在定义中只使用一种,比如C++学习者可以就使用分号(;)。
字段会有optional和required之分和protobuf一样,但是如果不指定则为无类型—可以不填充该值,但是在序列化传输的时候也会序列化进去,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();
    }

好了,本节主要讲解了如何将一个定义thrift service,生成了java中的接口,很可惜的地方是不支持泛型。下篇将讲解客户端和服务端的rpc通信。
参考资料:
1.https://www.cnblogs.com/duanxz/p/5516558.html
2.https://www.cnblogs.com/valor-xh/p/6386584.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容