apache thrift分析
thrift是一个用来实现跨语言的远程调用(RPC Remote Procedure Call)的软件框架。根据接口定义语言(IDL Interface definition lanuage) 并借助自身的协议栈和代码生成引擎来生成各种主流语言(C/C++,PYTHON,JAVA,GOLANG,PHP等)的rpc框架的服务端/客户端代码,使得在不同的语言之间可以提供高效的服务。
一:IDL支持的数据类型
- bool 布尔型
- byte 8位整数
- i16 16位整数
- i32 32位整数
- i64 64位整数
- double 双精度浮点数
- string 字符串
- binary 字节数组
- list<i16> List集合
- map<string, string> Map类型
- set<i32> Set集合
二: thrift 架构
服务端
+--------------------------------------------+
| Server |
| (single-threaded, event-driven etc) |
+-------------------------------------------+
| Processor |
| (compiler generated) |
+-------------------------------------------+
| Protocol |
| (JSON, compact etc) |
+-------------------------------------------+
| Transport |
| (raw TCP, HTTP etc) |
+-------------------------------------------+
| 底层IO Socket/File/Zip |
+-------------------------------------------+
客户端
+-------------------------------------------+
| Client |
+-------------------------------------------+
| Processor |
| (compiler generated) |
+-------------------------------------------+
| Protocol |
| (JSON, compact etc) |
+-------------------------------------------+
| Transport |
| (raw TCP, HTTP etc) |
+-------------------------------------------+
| 底层IO Socket/File/Zip |
+-------------------------------------------+
1、底层IO模块,负责实际的数据传输,包括socket,文件或者压缩数据流等
2、Transport 负责以字节流的方式发送和接收数据,是底层IO模块在thrift框架中的实现,每一个底层IO模块都会有一个对应TTransport来负责Thrift的字节流(Byte Stream)数据在该IO模块上的传输。例如TSocket对应Socket传输,TFileTransport对应文件传输。
3、Protocol(或TProtocol)主要负责结构化数据组装,或者从结构中读出结构化数据。TProtocol将一个有类型的数据转化为字节流以交给TTransport进行传输,或者从TTransport中读取一定长度的字节数据转化为特定类型的数据。如int32会被TBinaryProtocol Encode为一个四字节的字节数据,或者TBinaryProtocol从TTransport中取出四个字节的数据Decode为int32。
4、Processor(或者TProcessor)负责对Client的请求做出响应,包括RPC请求转发,调用参数解析和用户逻辑调用,返回值写回等处理步骤。Processor是服务器端从Thrift框架转入用户逻辑的关键流程
5、TServer负责接收Client的请求,并将请求转发到Processor进行处理。TServer主要任务就是高效的接受Client的请求,特别是在高并发请求的情况下快速完成请求
Thrift的模块设计非常好,在每一个层次都可以根据自己的需要选择合适的实现方式
Transport
transport这一层提供了一个抽象层,从网络上读取,发送数据。 这一层并不解析数据的类型,它只是一个字节一个字节的读取和发送数据
transport支持的几种传输类型:
1. TSocket 使用阻塞的Socket进行IO传输
2. TFramedTransport 使用一个带Buffer的Socket进行IO传输,使用NoblockingServer的时候会需要使用TFramedTransport
3. TFileTransport 使用文件进行IO传输
4. TZlibTransport 与其他的TTransport配合使用,完成数据的压缩传输
Protocol
Protocol的主要任务是把Transport中的字节流转化为数据流(Data Stream),在Protocol这一层就会出现具有数据类型的数据,如整型,浮点数,字符串,结构体等
Protocol中数据虽然有了数据类型,但是Protocol只会按照指定类型将数据读出和写入,而对于数据的真正用途,需要在Thrift自动生成的Server和Client中里处理
Protocol支持的几种主要协议类型为:
1. TBinaryProtocol 所有数据直接按照二进制方式编码
2. TCompactProtocol 高效的编码方式,使用了类似于ProtocolBuffer的Variable-Length Quantity (VLQ) 编码方式,主要思路是对整数采用可变长度,同时尽量利用没有使用Bit。
3. TDenseProtocol 类似于TCompactProtocol,但是传输过程中移除数据的Meta信息
4. TJSONProtocol 使用JSON编码数据
5. TSimpleJSONProtocol 只写方式的JSON编码,适合脚本语言的解析
6. TDebugProtocol 文本方式编码数据,主要用于调试
Processor
Processor是由Thrift生成的TProcessor的子类,主要对TServer中一次请求的 InputProtocol和OutputTProtocol进行操作,也就是从InputProtocol中读出Client的请求数据,向OutputProtcol中写入用户逻辑的返回值。Processor是TServer从Thrift框架转到用户逻辑的关键流程。同时TProcessor.process是一个非常关键的处理函数,因为Client所有的RPC调用都会经过该函数处理并转发
Server
Server在Thrift框架中的主要任务是接收Client的请求,并转到某个TProcessor上进行请求处理。针对不同的访问规模, Thrift提供了不同的TServer模型。Thrift目前支持的Server模型包括:
1. TSimpleServer 使用阻塞IO的单线程服务器,主要用于调试
2. TThreadedServer 使用阻塞IO的多线程服务器。每一个请求都在一个线程里处理,并发访问情况下会有很多线程同时在运行。
3. TThreadPoolServer 使用阻塞IO的多线程服务器,使用线程池管理处理线程。
4. TNonBlockingServer 使用非阻塞IO的多线程服务器,使用少量线程既可以完成大并发量的请求响应。该类型Server必须使用TFramedTransport。
Client
Client跟TProcessor一样都主要操作InputProtocol和OutputProtocol,不同的是Client将RPC调用分为Send和receive两个步骤。
1. Send步骤,将用户的调用参数作为一个整体的Struct写入TProcotol,并发送到TServer。
2. Send结束之后,Client便立刻进入Receive状态等待TServer的相应。对于TServer返回的响应,使用返回值解析类进行返回值解析,完成RPC调用。
参考资料:
http://thrift.apache.org/docs/
https://developers.google.com/protocol-buffers/docs/encoding
http://thrift.apache.org/tutorial/
http://thrift.apache.org/static/files/thrift-20070401.pdf
https://blog.csdn.net/column/details/thrift.html