Thrift是一个跨平台的服务部署框架,最初是由Facebook开发的。Thrift通过一个中间语言( IDL,接口定义语言)来定义RPC接口和数据类型,然后通过一个编译器生成不同类型的代码(目前支持的语言有: C++,Java,Python,PHP, Ruby,Erlang…) ,并由生成的代码负责RPC协议层和传输层的实现。
Thrift实质上是以C/S 模式来实现的,通过代码生成工具将接口定义文件来生成服务器和客户端的代码,从而实现了服务端和客户端跨平台语言的支持。用户在Thrift描述文件中声明自己的服务,这些服务经过编译后就会生成相应语言的代码文件,然后客户端调用远程服务,调用远程服务的信息会被客户端中通过描述文件生成的客户端存根所捕获到,之后客户端存根将会将调用信息{调用的方法的返回值类型,参数类型及参数实体,远程调用的方法名称等等} 打包成网络信息包的格式,然后将其信息包交付给客户端的内核中,有客户端的内核将其消息发送到服务器端的内核陷阱中,内核陷阱将其交付给服务器存根程序,服务器存根程序将从接收到的信息报中提出所需调用的本地方法的名称,还有方法所需参数,之后,会根据这些信息调用本地实体方法,然后得到方法运行之后的结果,之后以同样的方式将改结果打包经由存根程序、内核发送至客户端,然后又客户端的存根程序交付给请求远程调用的应用程序。
其中protocol( 协议层,用以定义数据传输格式,可以为二进制或者是XML等等数据类型) 和transport ( 传输层,定义的是数据传输的方式,可以以TCP/IP 的协议进行传输,内存共享或是文件共享等等)被用作运行时库。
Thrift 支持多种数据传输格式,数据传输方式和服务器模型的定义方式
<服务器模型的定义方式所指的是:服务器接收客户端请求的方式以及处理客户端请求的方式(并发或是单线程,是否提供缓存,以及发送接收信息的方式是阻塞还是非阻塞的)>
(协议层)Thrift 所支持的数据传输格式
TBinaryProtocol - 二进制数据传输格式
TCompactProtocol - 压缩格式
TJSONProtocol - JSON格式
TSimpleJSONProtocol - 只写JSON格式,此种格式所描述的文件时很容易通过脚本语言来对其进行解析的。
(传输层) Thrift 所支持的数据传输方式
TSocket - 这种方式是阻塞式的socker
TFramedTransport -这种传输是以frame 为单位进行的传输,通常使用在非阻塞式的服务中。
TFileTransport - 这种数据传输方式是以文件为载体的形式对数据进行传输
TMemoryTransport - 这个是将内存用于I/O , java在实现的时候内部使用了简单的ByteArrayOutputStream
TZlibTransport - 使用zlib进行压缩,与其他的传输方式联合使用,目前还没有使用java语言对其进行实现。
支持的服务模型
<这里所说的服务模型指的是,服务器是以和中方式来响应接收客户端的请求服务: 是以 单线程,还是多线程; 是以阻塞的通信方式,还是以 非阻塞的通信方式 ; 是为来不及相应的请求开辟缓冲区进行缓存, 还是不提供临时缓存空间 >
TSimpleServer-- 这种服务器模型是基于单线程的相应方式,服务器接收并响应客户端的程序的时候,通常是创建一个死循环,不断的接收请求,执行请求,然后释放连接,进行下一次的接收请求。
TThreadPoolServer – 这种服务器模型基于的是多线程的服务模型,即通常是这样组织的: 在多线程中有一个协调者,协调者负责接收来自各个客户端
的请求,将其分配各各个工作者进行,工作者进程则是负责调用服务器端的实体方法运行程序并得到结果,该执行结果通过协调者发送至提出请求的客户端。
TNonblockingServer – 这种服务器模型也是基于多线程的服务模型,但是它提供的服务是非阻塞 I/O 的。
Protobuf 是Protocol Buffer的缩写,简称是PB,是google公司开发的一种数据交换格式,是一种独立于语言,独立于平台,在各种语言中处于中立地位的一种开发语言。
google针对protobuf 的开发提供了三种常用的语言实现: Java, C++ 和 Python, 每一种语言的实现中都包含了相关语言的编译器及它的库文件。
由于Protobuf是一种二进制的格式来进行数据表示和传输,所以比使用XML文件来进行数据交换要快得多。
以此优点而常被用在分布式系统设计中担任系统中多个节点之间的数据传输工作。也常常用于异构的环境下进行数据的交换以及RPC底层框架的搭建工作。
Protobuf作为一种效率和兼容性很优秀的二进制数据传输格式,广泛的使用在例如网络传输、文件配置、数据存储等等相关诸多领域。
其中的IO子系统是最为简单的,它与其他系统部分没有依赖关系,实现了统一的输入输出接口。
Message抽象层: 对于Message抽象层主要由一个抽象的Message抽象类和从Message类里面单独分离出来的Reflection类构成。
GeneratedMessageReflection是Reflection的派生类, 它实现了抽象Message的方法,这里的关键之处在于一个静态的offsets的数组,在这个数组里面存储了任何Message派生类对象里面的各个字段相对于对象本身的偏移量。通过偏移量的指示,GeneratedMessageReflection可以在不知道确切名字和类型的情况下实现Reflection里面所定义的Message的方法。
Descriptor抽象层: 对于Descriptor抽象层是整个系统的核心,它是由平行的两组解释器组成的。一组是一系列递归下降的Descriptor类群,另一组是一系列递归下降的DescriptorProto的类群。Descriptor类群描述的是抽象的任意的消息。
DescriptorProto类型是对消息格式本身进行描述的消息,其中FileDescriptorProto类群描述了 .proto 文件的结构,任何.proto 文件都是可以映射到一个FileDescriptorProto 对象上的。
FileDescriptor对象与FileDescriptorProto 对象之间是相互转换的。