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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容