Thrift基础概念

Thrift基础概念

文章目录

  • Thrift基础概念
    • Thrift的网络栈
      • Transport
      • Protocol
      • Processor
      • Server
    • Thrift 的特性
      • 不支持的特性
    • Thrift 的类型
      • Base Types
      • Special Types
      • Structs
      • Containers
      • Exceptions
      • Services

Java实现Thrift实例

Thrift的网络栈

简单的Thrift网络栈图示

  +-------------------------------------------+
  | Server                                    |
  | (single-threaded, event-driven etc)       |
  +-------------------------------------------+
  | Processor                                 |
  | (compiler generated)                      |
  +-------------------------------------------+
  | Protocol                                  |
  | (JSON, compact etc)                       |
  +-------------------------------------------+
  | Transport                                 |
  | (raw TCP, HTTP etc)                       |
  +-------------------------------------------+

Transport

传输层为网络的读写提供了一个简单的抽象。这使得Thrift能够将底层传输与系统的其余部分(例如序列化/反序列化)解耦。

以下是Transport接口暴露的一些方法:

  • open
  • close
  • read
  • write
  • flush

除了上面的Transport接口,Thrift还使用ServerTransport接口来接受或创建原始传输对象。顾名思义,ServerTransport主要用于服务器端,用于为传入连接创建新的Transport对象。

  • open
  • listen
  • accept
  • close

以下是大多数thrift支持的语言可以使用的一些传输:

  • file: read/write to/from a file on disk 对磁盘上的文件进行读写
  • http: as the name suggests 顾名思义

Protocol

协议抽象定义了一种将内存中的数据结构映射到有线格式的机制。换句话说,协议规定了数据类型如何使用底层Transport对自身进行编码/解码。因此,协议实现控制编码方案并负责(反)序列化。在这个意义上,协议的一些例子包括JSON、XML、纯文本、压缩二进制等。

有线格式在广义上指的是用于在内存或硬盘上表达数据的格式,“XML/JSON wire format” 是特定物理表达形式(physical representation,实际表达形式)的实例。其中,对于数据的表达格式,如数据类型等进行了规定。XML/JSON wire format描述的是依据W3C相关技术规范所编写的特定消息/文档的物理表达形式。此类格式之中规定的是用于在运行时环境下解析或写入XML/JSON消息/文档的相关信息。

Protocol 接口:

writeMessageBegin(name, type, seq)
writeMessageEnd()
writeStructBegin(name)
writeStructEnd()
writeFieldBegin(name, type, id)
writeFieldEnd()
writeFieldStop()
writeMapBegin(ktype, vtype, size)
writeMapEnd()
writeListBegin(etype, size)
writeListEnd()
writeSetBegin(etype, size)
writeSetEnd()
writeBool(bool)
writeByte(byte)
writeI16(i16)
writeI32(i32)
writeI64(i64)
writeDouble(double)
writeString(string)

name, type, seq = readMessageBegin()
                  readMessageEnd()
name = readStructBegin()
       readStructEnd()
name, type, id = readFieldBegin()
                 readFieldEnd()
k, v, size = readMapBegin()
             readMapEnd()
etype, size = readListBegin()
              readListEnd()
etype, size = readSetBegin()
              readSetEnd()
bool = readBool()
byte = readByte()
i16 = readI16()
i32 = readI32()
i64 = readI64()
double = readDouble()
string = readString()

Thrift 协议在设计上面向数据流的。不需要任何明确的框架。例如,在开始序列化之前,我们不需要知道字符串的长度或列表中的items数。大多数支持 Thrift 的语言都可以使用以下协议:

  • binary 相当简单的二进制编码–字段的长度和类型以字节形式编码,后面是字段的实际值。
  • compact 描述于 THRIFT-110
  • json

Processor

处理器封装了从输入流读取数据和向输出流写入数据的能力。输入和输出流由Protocol对象表示。Processor接口非常简单

interface TProcessor {
    bool process(TProtocol in, TProtocol out) throws TException
}

特定于服务的处理器实现由编译器生成。处理器本质上是从连接中读取数据(使用输入协议),将处理委托给处理程序(由用户实现),并通过连接(使用输出协议)写入响应。

Server

服务器汇集了上述所有功能:

  • 创建传输
  • 为传输创建输入/输出协议
  • 根据输入/输出协议创建处理器
  • 等待传入连接并将其交给处理器

Thrift 的特性

  • 接口描述语言–所有内容都在 IDL 文件中指定,可从中生成多种语言的绑定。参见 Thrift IDL
  • language bindings - Thrift 支持多种语言和环境
    • C++
    • C#
    • Cocoa
    • D
    • Delphi
    • Erlang
    • Haskell
    • Java
    • OCaml
    • Perl
    • PHP
    • Python
    • Ruby
    • Smalltalk
  • namespaces - 每个Thrift文件都有自己的名称空间,允许您在多个Thrift文件中使用相同的标识符
  • language namespaces - 对于Thrift文件,您可以指定每种编程语言应该使用哪个名称空间
  • base types - Thrift有一个小的基本类型集。 See Thrift Types
  • constants and enumerations - 常量值可以被赋予逻辑名称
  • structs -使用structs对相关数据进行分组。结构体可以有任何类型的字段。See Thrift Types
  • sparse structs - 尚未设置的可选基本字段和为空的引用字段将不会通过网络发送
  • struct evolution - 通过使用字段的整数标识符来处理字段的添加和删除,而不会破坏现有的客户端
  • containers - 您可以使用任何类型的sets、lists 和maps :基础类型、structs 和其他容器。See Thrift Types
  • type definitions - 任何类型都可以被赋予一个更好地描述它的名称
  • services - 服务是一组功能
  • service inheritance - 子服务实现其基本服务的所有功能,并且可以具有附加功能
  • asynchronous invocations - 可以异步调用不返回结果的函数,这样在服务器完成处理请求之前,客户端不会被阻塞。 服务器可并行/不按顺序执行对同一客户端的异步调用
  • exceptions - 如果发生错误,函数可以抛出标准或用户定义的异常。See Thrift Types
  • cyclic structs - 从0.9.2版本开始,Thrift支持包含自身的结构,或者稍后声明的其他结构。

不支持的特性

Apache Thrift 不支持以下内容:

  • 结构继承 - 使用结构组合代替
  • 多态性 - 由于不存在继承,因此也不支持多态性
  • 重载–服务中的所有方法都必须唯一命名
  • 异构容器 - 容器中的所有项目必须具有相同类型
  • 空返回 - 函数不能直接返回Null。请使用包装器结构体或标记值

Thrift 的类型

Thrift类型系统旨在允许程序员尽可能多地使用原生类型,无论他们使用哪种编程语言。此信息基于并取代了Thrift白皮书中的信息。Thrift IDL提供了用于为每种目标语言生成代码的类型的描述。

Base Types

选择基本类型的目标是简单明了,而不是复杂多样,重点关注所有编程语言中可用的关键类型。

  • bool: A boolean value (true or false)
  • byte: An 8-bit signed integer
  • i16: A 16-bit signed integer
  • i32: A 32-bit signed integer
  • i64: A 64-bit signed integer
  • double: A 64-bit floating point number
  • string: A text string encoded using UTF-8 encoding

注意没有无符号整数类型。这是因为许多编程语言都没有本地无符号整数类型。

Special Types

binary: a sequence of unencoded bytes 一个未编码的字节序列

注:目前,这是上述字符串类型的一种特殊形式,是为了更好地与 Java 互操作而添加的。目前的计划是在某个时候将其提升为基本类型。

Structs

Thrift 结构定义了一个通用对象–它们本质上等同于 OOP 语言中的类,但没有继承性。结构体有一组强类型字段,每个字段都有一个唯一的名称标识符。字段可以有各种注释(数字字段 ID、可选默认值等),这些注释在Thrift IDL中都有描述。

Containers

Thrift 容器是强类型的容器,可以映射到大多数编程语言中常用和可用的容器类型。

有三种容器类型:

  • list: 元素的有序列表。可转换为 STL 向量、Java ArrayList、脚本语言中的本地数组等。
  • set: 包含唯一元素的无序集合。可转换为 STL 集合、Java HashSet、Python 中的集合等。注:PHP 不支持集合,因此其处理方式类似于 List
  • map: 严格唯一的键值映射。可转换为 STL map、Java HashMap、PHP 关联数组、Python/Ruby 字典等。虽然提供了默认值,但并没有明确固定类型映射。已添加了自定义代码生成器指令,允许在各种目标语言中替换自定义类型。

容器元素可以是任何有效的 Thrift 类型。

注:为获得最大兼容性,map 的键类型应为基本类型,而不是结构或容器类型。有些语言的本地映射类型不支持更复杂的键类型。此外,JSON 协议只支持基本类型的键类型。

Exceptions

异常在功能上等同于结构体,只不过它们在每种目标编程语言中都继承了原生异常基类,以便与任何特定语言中的本地异常处理无缝集成。

Services

服务使用 Thrift 类型定义。定义服务在语义上等同于在面向对象编程中定义接口(或纯虚拟抽象类)。Thrift 编译器会生成实现接口的功能完备的客户端和服务器存根。

服务由一组命名函数组成,每个函数都有一个参数列表和一个返回类型。

请注意,除了所有其他已定义的 Thrift 类型外,void 也是函数返回的有效类型。此外,还可以在 void 函数中添加单向修饰关键字,这样生成的代码将不会等待响应。请注意,纯 void 函数会向客户端返回一个响应,以保证服务器端的操作已经完成。而单向方法调用只能保证客户端在传输层请求成功。同一客户端的单向方法调用可能会被服务器并行或不按顺序执行。

你可能感兴趣的:(JAVA,php,开发语言)