一直在工作中使用 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主要包含以下接口:
除了上面这个Transport的接口,Thrift还提供了一个ServerTransport的接口,用来accept或者create上面的Transport对象。顾名思义,ServerTransport主要用在服务端,用来接受连接并创建Transport对象。
ServerTransport主要包含以下接口:
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
- json
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
- 等待并处理连接