Thrift入门

作者: 雁宇 | 来源:发表于2017-07-22 11:51 被阅读131次

    简介

    Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。
    它通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#、C++(基于POSIX兼容系统)、Cappuccino、Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。
    另外,Thrift早期由Facebook开发,目前已成为Apache软件基金会的开源项目。

    基本架构

    类似于计算机网络,Thrift包含一套完整的栈来创建客户端和服务端程序。

    • 顶层部分是由Thrift定义生成的代码。而服务则由这个文件客户端和处理器代码生成。在生成的代码里会创建不同于内建类型的数据结构,并将其作为结果发送。
    • 协议层和传输层是运行时库的一部分。有了Thrift,就可以定义一个服务或改变通讯和传输协议,而无需重新编译代码。除了客户端部分之外,Thrift还包括服务器基础设施来集成协议和传输,如阻塞、非阻塞及多线程服务器。
    • IO层在栈中作为基础部分对于不同的语言则有不同的实现。
    Thrift的栈结构

    使用

    快送入门

    根据官网,使用Thrift前需要下载Thrift并且构建和安装Thrift编译器。
    在使用Thrift进行编程时,需要以下几步(详细过程可见Apache Thrift Tutorial):

    1. 创建.thrift文件
    2. 使用Thrift编译器编译为特定语言的源码
    3. 根据源码实现服务的功能

    其实,如果你是一个Java开发者,使用Thrfit有一个更好的方式:借助Swift(并不是指苹果的Swift语言)。使用Swift,你可以告别书写thrift文件并且进行多余的一步编译,而且也不用忍受由thrift生成的冗长的Java文件,一切都可以用Java代码和注解搞定😎

    样例代码thrift_demo已提交码云

    Thrift IDL

    IDL即为Interface Description Language,对于Thrift有其特定的语法。详细内容可以参考:Thrift interface description language

    PS:若采用Jetbrains出品的IDE,可以安装Thrift Support插件来对Thrift语法做出支持。

    原有数据类型

    基本类型

    • 布尔型:bool
    • 整型:byte、i16、i32、i64
    • 浮点型:double
    • 字符串:string(utf8编码)

    容器类型

    • 有序可重复:list<t>(对应Java的ArrayList)
    • 无序不可重复:set<t>(对应Java的HashSet)
    • 关联容器:map<k,v>(对应Java的HashMap)

    可定制数据类型

    结构体类型

    struct关键字定义,需要给字段提供数字标签,示例如下:

    struct PersonVo{
        1:required i32 id,
        2:required string name,
        3:required double wealth
    }
    

    说明:

    1. 字段可以采用=来设置默认值。
    2. 数字标签不要轻易修改。在修改时可以考虑新加一个数字标签,丢弃原有的字段。
    3. 字段前标识required表示,该字段必填,自然传输时必然会序列化;字段前无标识,表示可以不填充,但一定会序列化;字段前标识optional表示该字段,可以不填充,并且不填充也不会序列化。

    异常类型

    异常类型的定义和结构体基本相同,但采用exception作为关键字。

    枚举类型

    采用enum作为关键字定义,示例如下:

    enum ColorEnum{
        WHITE = 0;
        BLACK = 1;
        BLUE = 2;
    }
    

    常量类型

    采用const关键字定义,示例如下:

    const i32 INT_CONST = 1234; 
    

    服务类型

    使用service关键字定义,用于描述接口,类似于Java中的接口文件。示例如下:

    service PersonService {
        PersonDomain.PersonVo get(1:i32 id);
        oneway void add(1:PersonDomain.PersonVo pv);
    }
    

    说明:

    • 所有的参数都是const类型,不能作为返回值
    • oneway关键字用来表示client发出请求后不必等待回复(非阻塞)直接进行下面的操作。所以其返回值一定为void
    • 继承类必须实现这些方法。
    • 服务支持继承,一个service可使用extends关键字继承另一个service。
    • 服务中的函数不支持重载。

    文件间关系

    定义本文件的所处的命名空间可以采用namespace关键字,其效果同Java中的包。使用命名空间后需指定语言类型,如java。示例如下:

    namespace java demo.thrift
    

    使用其他文件的内容需要使用include后接其他文件名,其他文件名需要用单引号修饰。示例如下:

    include 'PersonDomain.thrift'
    

    其他

    • Thrift支持C多行风格和Java/C++单行风格。
    • typedef用于定义数据结构别名

    传输体系

    传输体系由传输协议和传输方式构成,具体内容在和 Thrift 的一场美丽邂逅一文中有更为详细的说明,这里就是粗略枚举一些。

    传输协议

    • TBinaryProtocol:是Thrift的默认协议,使用二进制编码格式进行数据传输,基本上直接发送原始数据
    • TCompactProtocol:压缩的、密集的数据传输协议,基于Variable-length quantity的zigzag 编码格式
    • TJSONProtocol:以JSON (JavaScript Object Notation)数据编码协议进行数据传输
    • TDebugProtocol:常常用以编码人员测试,以文本的形式展现方便阅读
    • ...

    传输方式

    • TFileTransport:该传输协议会写文件。
    • TFramedTransport:当使用一个非阻塞服务器时,要求使用这个传输协议。它按帧来发送数据,其中每一帧的开头是长度信息。
    • TMemoryTransport:使用存储器映射输入输出。(Java的实现使用了一个简单的ByteArrayOutputStream。)
    • TSocket:使用阻塞的套接字I/O来传输。
    • TZlibTransport:用zlib执行压缩。用于连接另一个传输协议。
    • ...

    服务器

    Thrift自带了一些好用的服务器程序,以Java为例,大致有下面这些:

    • TNonblockingServer:一个多线程服务器,它使用非阻塞I/O(Java的实现使用了NIO通道)。TFramedTransport必须跟这个服务器配套使用。
    • TSimpleServer:一个单线程服务器,它使用标准的阻塞I/O。测试时很有用。
    • TThreadPoolServer:一个多线程服务器,它使用标准的阻塞I/O。
    • ...

    参照

    相关文章

      网友评论

        本文标题:Thrift入门

        本文链接:https://www.haomeiwen.com/subject/rxqukxtx.html