5

Thrift 相关概念学习笔记

 3 years ago
source link: https://www.purewhite.io/2019/09/23/thrift-concepts-notes/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Thrift 相关概念学习笔记

2019-09-23后端 217
2.2k 4 分钟

一直在工作中使用 Apache Thrift,但是一直对其中的一些概念一知半解,于是终于抽空学习了一下,记录下来作为学习笔记。

Thrift 网络层级

简单示意图如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
+-------------------------------------------+
| Server |
| (single-threaded, event-driven etc) |
+-------------------------------------------+
| Processor |
| (compiler generated) |
+-------------------------------------------+
| Protocol |
| (JSON, compact etc) |
+-------------------------------------------+
| Transport |
| (raw TCP, HTTP etc) |
+-------------------------------------------+

Transport

Transport 层提供了一个读写底层网络的简单抽象,这使得 Thrift 可以把底层的网络传输和其它部分(比如序列化、反序列化)解耦开。

Transport 主要包含以下接口:

  • close
  • write
  • flush

除了上面这个 Transport 的接口,Thrift 还提供了一个 ServerTransport 的接口,用来 accept 或者 create 上面的 Transport 对象。顾名思义,ServerTransport 主要用在服务端,用来接受连接并创建 Transport 对象。

ServerTransport 主要包含以下接口:

  • listen
  • accept
  • close

Thrift 主要支持的语言中有的部分接口示例如下:

  • file: read/write to/from a file on disk
  • http: 顾名思义

Protocol

Protocol 层定义了序列化、反序列化的格式和方法,比如 json、xml、plain text、compact binary 等等。

Protocol 的接口定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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 Protocol 在设计上就是以流为目标的,所以不需要任何显式的帧。比如,当我们在序列化一个 string 之前,我们不需要知道它有多长;同样的,当我们序列化一个 list 之前,不需要知道里面有几个 item。部分 Thrift 主要支持语言所常用的 Protocol 如下:

  • binary: 非常简单的二进制编码,先编码长度和类型,然后编码真实的值。
  • compact: 参考 THRIFT-110

Processor

Processor 提供了从输入流读取数据以及写出到输出流的能力,输入和输出流都是由 Protocol 层实现,Processor 本身很简单:

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

每个服务的 Processor 都是由 compiler 生成的,Processor 从输入流读取数据,扔给用户的 handler 处理,再把 response 写回输出流。

Server

Server 把上述所有的特性组合在一起:

  • 创建一个 Transport
  • 根据 Transport 创建输入输出流(Protocol)
  • 基于输入输出流创建 Processor
  • 等待并处理连接

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK