Apache Thrift介绍

文章目录

    • 1、简介
    • 2、Thrift IDL
      • 2.1、基本类型
      • 2.2、结构体struct
      • 2.3、容器Container
      • 2.4、枚举enum
      • 2.5、常量定义
      • 2.6、类型定义
      • 2.7、异常Exception
      • 2.8、服务定义类型Service
      • 2.9、名字空间NameSpace
      • 2.10、注释Comment
      • 2.11、include
    • 3、thrift架构
    • 4、thrift协议
    • 5、数据传输方式
    • 6、服务模型

1、简介

thrift官网
Apache Thrift软件框架用于可伸缩的跨语言服务开发,它将软件栈和代码生成引擎结合在一起,以构建在c++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、c#、Cocoa、JavaScript、Node.js、Smalltalk、OCaml和Delphi等语言之间高效、无缝地工作的服务。

Thrift使用C++进行编写,在安装使用的时候需要安装依赖,windows安装方式见官网即可,本人采用的是Mac如按照官网所说安装则过于麻烦,因此在这里推荐使用homebrew的Mac包管理器进行安装,它会帮助我们安装需要的依赖。安装方式:thrift官网介绍安装方式

2、Thrift IDL

Thrift 采用IDL(Interface Definition Language)来定义通用的服务接口,然后通过Thrift提供的编译器,可以将服务接口编译成不同语言编写的代码,通过这个方式来实现跨语言的功能。

2.1、基本类型

bool: 布尔值 对应Java中的boolean
byte: 有符号字节 对应Java中的byte
i16: 16位有符号整型 对应Java中的short
i32: 32位有符号整型 对应Java中的int
i64: 64位有符号整型 对应Java中的long
double: 64位浮点型 对应Java中的double
string: 字符串 对应Java中的String
binary: Blob 类型 对应Java中的byte[]

2.2、结构体struct

struct有以下一些约束:

1.struct不能继承,但是可以嵌套,不能嵌套自己。(0.12.0版本可以支持嵌套自己本身)
2.其成员都是有明确类型
3.成员是被正整数编号过的,其中的编号使不能重复的,这个是为了在传输过程中编码使用。
4.成员分割符可以是逗号(,)或是分号(;),而且可以混用
5.字段会有optional和required之分和protobuf一样,但是如果不指定则为无类型–可以不填充该值,但是在序列化传输的时候也会序列化进去,optional是不填充则部序列化,required是必须填充也必须序列化。
6.每个字段可以设置默认值
7.同一文件可以定义多个struct,也可以定义在不同的文件,进行include引入。

举个简单的下例子:

struct Person{
  1: required string name, //本字段必须填写
  2: optional i32 age = 0; //默认值
  3: bool gender //默认字段类型是optional
}

规则:

  • 如果required标识的域没有赋值,Thrift将给予提示;
  • 如果optional标识的域没有赋值,该域将不会被序列化传输;
  • 如果某个optional标识域有缺省值而用户没有重新赋值,则该域的值一直为缺省值;
  • 如果某个optional标识域有缺省值或者用户已经重新赋值,而不设置它的__isset为true,也不会被序列化传输。

2.3、容器Container

thrift提供三种容器选择:

  • list: 元素类型为t的有序表,容许元素重复。对应C++的vector和Java的ArrayList或者其他语言的数组集合
  • set: 元素类型为t的无序表不容许元素重复。对应C++中的set和Java中的HashSet和python中的set,php中没有set需要转换为list类型
  • map: 键类型为t,值类型为t的kv对,键不容许重复。对用C++中的map, Java的HashMap, PHP 对应 array, Python/Ruby 的dictionary

简单的demo:

struct Test {
  1: map<string, Person> usermap,
  2: set<i32> intset,
  3: list<double> doublelist
}

2.4、枚举enum

约束

  • 编译器默认从0开始赋值
  • 可赋予某个常量某个整数
  • 允许常量是十六进制整数
  • 末尾无分号
  • 给常量赋缺省值时,使用常量的全称

规则

Thrift不支持枚举类嵌套,枚举常量必须是32位的正整数

简单的demo:

enum HttpStatus {
  OK = 200,
  NOTFOUND=404
}

2.5、常量定义

使用方法:在变量前面加上const

简单的例子:

const i32 const_int = 1;

2.6、类型定义

Thrift支持C/C++类型定义

简单的demo:

typedef i32 myint
typedef i64 usernumber

末尾没有逗号

2.7、异常Exception

异常在语法和功能上类似于结构体,差别是异常使用关键字exception,而且异常是继承每种语言的基础异常类。

简单的demo:

exception MyException {
    1: i32 errorCode,
    2: string message
}

2.8、服务定义类型Service

服务的定义方法在语义上等同于面向对象语言中的接口。

service HiService {
    i32 sayInt(1:i32 param)
    string sayString(1:string param)
    bool sayBoolean(1:bool param)
    void sayVoid()
}

2.9、名字空间NameSpace

Thrift中的命名空间类似于C++中的namespace和java中的package,它们提供了一种组织(隔离)代码的简便方式。名字空间也可以用于解决类型定义中的名字冲突。

由于每种语言均有自己的命名空间定义方式(如python中有module), thrift允许开发者针对特定语言定义namespace。

简单的demo:

namespace java com.xtxxtx.test

转换成

package com.xtxxtx.test

2.10、注释Comment

Thrift支持C多行风格和Java/C++单行风格。

简单的小demo:

/** 
 * This is a multi-line comment. 
 * Just like in C. 
 */
 // C++/Java style single-line comments work just as well.

2.11、include

便于管理、重用和提高模块性/组织性,我们常常分割Thrift定义在不同的文件中。包含文件搜索方式与C++一样。Thrift允许文件包含其它thrift文件,用户需要使用thrift文件名作为前缀访问被包含的对象,

简单的demo:

include "test.thrift"   
...
struct StSearchResult {
    1: in32 uid;
     ...
}

thrift文件名要用双引号包含,末尾没有逗号或者分号。

3、thrift架构

Thrift 包含一个完整的堆栈结构用于构建客户端和服务器端。下图描绘了 Thrift 的整体架构:
Apache Thrift介绍_第1张图片
图中黄色部分是用户实现的业务逻辑,褐色部分是根据 Thrift 定义的服务接口描述文件生成的客户端和服务器端代码框架,红色部分是根据 Thrift 文件生成代码实现数据的读写操作。红色部分以下是 Thrift 的传输体系、协议以及底层 I/O 通信,使用 Thrift 可以很方便的定义一个服务并且选择不同的传输协议和传输层而不用重新生成代码。

Thrift 服务器包含用于绑定协议和传输层的基础架构,它提供阻塞、非阻塞、单线程和多线程的模式运行在服务器上,可以配合服务器 / 容器一起运行,可以和现有的 J2EE 服务器 /Web 容器无缝的结合。

4、thrift协议

  1. TBinaryProtocol —— 二进制编码格式进行数据传输
  2. TCompactProtocol —— 高效率的、密集的二进制编码格式进行数据传输
  3. TJSONProtocol —— 使用 JSON 的数据编码协议进行数据传输
  4. TSimpleJSONProtocol —— 只提供 JSON 只写的协议,适用于通过脚本语言解析
  5. TDebugProtocol —— 使用简单易懂的可读文本格式,便于debug

5、数据传输方式

  1. TSocket —— 使用阻塞式 I/O 进行传输,是最常见的模式
  2. TFramedTransport —— 使用非阻塞方式,按块的大小进行传输,类似于 Java 中的 NIO
  3. TFileTransport —— 使用文件形式进行传输
  4. TMemoryTransport —— 将内存用于I/O,Java实现内部实际使用简单的ByteArrayOutputStream
  5. TZlibTransport —— 使用Zlib进行压缩,与其他传输方式联合使用,当前无Java实现

6、服务模型

  1. TSimpleServer —— 单线程服务器端使用标准的阻塞式 I/O
  2. TThreadPoolServer —— 多线程服务器端使用标准的阻塞式 I/O
  3. TNonblockingServer —— 多线程服务器端使用非阻塞式 I/O
  4. THsHaServer —— THsHa引入线程池去处理,其模型把读写任务放到线程池中去处理;Half-sync/ Half-async的处理模式,Half-async在处理I/O事件上(accept/read/write io),Half-sync用于Handler对RPC的同步处理

你可能感兴趣的:(Netty)