1.什么是thrift?
thrift早期由facebook内部团队开发,主要用于实现跨语言间的方法调用,属于远程方法调用的一种,后开源纳入apache中,成为了apache thrift项目。
thrift允许定义一个简单的定义文件中的数据类型和服务接口,以作为输入文件,编译器生成代码用来方便地生成rpc客户端和服务器通信的无缝跨编程语言。
2.什么是rpc?
rpc (remote procedure call protocol),远程过程调用协议。
简单的说,rpc就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法并得到返回的结果。
rpc 会隐藏底层的通讯细节(不需要直接处理socket通讯或http通讯) rpc 是一个请求响应模型。
客户端发起请求,服务器返回响应(类似于http的工作方式) rpc 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。
thrift栈结构
thrift数据类型
基本类型:
bool:布尔值,true 或 false,对应 java 的 boolean
byte:8 位有符号整数,对应 java 的 byte
i16:16 位有符号整数,对应 java 的 short
i32:32 位有符号整数,对应 java 的 int
i64:64 位有符号整数,对应 java 的 long
double:64 位浮点数,对应 java 的 double
string:未知编码文本或二进制字符串,对应 java 的 string
结构体类型:
struct:定义公共的对象,类似于 c 语言中的结构体定义,在 java 中是一个 javabean
容器类型:
list:对应 java 的 arraylist
set:对应 java 的 hashset
map:对应 java 的 hashmap
异常类型:
exception:对应 java 的 exception
服务类型:
service:对应服务的类
生成thrift的java代码
http://thrift.apache.org/download
namespace java service.demo service hello{ string hellostring(1:string para) i32 helloint(1:i32 para) bool helloboolean(1:bool para) void hellovoid() string hellonull() }
hello.java内容
(1)异步客户端类asyncclient和异步接口asynciface
(2)同步客户端类client和同步接口iface,client类继承自tserviceclient,并实现了同步接口iface;iface就是根据thrift文件中所定义的接口函数所生成;client类是在开发thrift的客户端程序时使用,client类是iface的客户端存根实现, iface在开发thrift服务器的时候要使用,thrift的服务器端程序要实现接口iface。
(3)processor类,该类主要是开发thrift服务器程序的时候使用,该类内部定义了一个map,它保存了所有函数名到函数对象的映射,一旦thrift接到一个函数调用请求,就从该map中根据函数名字找到该函数的函数对象,然后执行它;
(4)参数类,为每个接口函数定义一个参数类,例如:为接口helloint产生一个参数类:helloint_args,一般情况下,接口函数参数类的命名方式为:接口函数名_args;
(5)返回值类,每个接口函数定义了一个返回值类,例如:为接口helloint产生一个返回值类:helloint_result,一般情况下,接口函数返回值类的命名方式为:接口函数名_result;
参数类和返回值类中有对数据的读写操作,在参数类中,将按照协议类将调用的函数名和参数进行封装,在返回值类中,将按照协议规定读取数据。
client
iface
helloserviceimpl
调用过程
thrift调用过程中,thrift客户端和服务器之间主要用到传输层类、协议层类和处理类三个主要的核心类,这三个类的相互协作共同完成rpc的整个调用过程
(1) 将客户端程序调用的函数名和参数传递给协议层(tprotocol),协议层将函数名和参数按照协议格式进行封装,然后封装的结果交给下层的传输层。此处需要注意:要与thrift服务器程序所使用的协议类型一样,否则thrift服务器程序便无法在其协议层进行数据解析;
(2) 传输层(ttransport)将协议层传递过来的数据进行处理,例如传输层的实现类tframedtransport就是将数据封装成帧的形式,即“数据长度+数据内容”,然后将处理之后的数据通过网络发送给thrift服务器;此处也需要注意:要与thrift服务器程序所采用的传输层的实现类一致,否则thrift的传输层也无法将数据进行逆向的处理;
(3) thrift服务器通过传输层(ttransport)接收网络上传输过来的调用请求数据,然后将接收到的数据进行逆向的处理,例如传输层的实现类tframedtransport就是将“数据长度+数据内容”形式的网络数据,转成只有数据内容的形式,然后再交付给thrift服务器的协议类(tprotocol);
(4) thrift服务端的协议类(tprotocol)将传输层处理之后的数据按照协议进行解封装,并将解封装之后的数据交个processor类进行处理;
(5) thrift服务端的processor类根据协议层(tprotocol)解析的结果,按照函数名找到函数名所对应的函数对象;
(6) thrift服务端使用传过来的参数调用这个找到的函数对象;
(7) thrift服务端将函数对象执行的结果交给协议层;
(8) thrift服务器端的协议层将函数的执行结果进行协议封装;
(9) thrift服务器端的传输层将协议层封装的结果进行处理,例如封装成帧,然后发送给thrift客户端程序;
(10) thrift客户端程序的传输层将收到的网络结果进行逆向处理,得到实际的协议数据;
(11) thrift客户端的协议层将数据按照协议格式进行解封装,然后得到具体的函数执行结果,并将其交付给调用函数;
服务端
客户端
输出结果
协议和传输方式
thrift 可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本 (text) 和二进制 (binary) 传输协议,为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数,有时还会使用基于文本类型的协议,这需要根据项目 / 产品中的实际需求。常用协议有以下几种:
tbinaryprotocol:是thrift的默认协议,使用二进制编码格式进行数据传输,基本上直接发送原始数据
tcompactprotocol:压缩的、密集的数据传输协议,基于variable-length quantity的zigzag 编码格式
tjsonprotocol:以json (javascript object notation)数据编码协议进行数据传输
tdebugprotocol:常常用以编码人员测试,以文本的形式展现方便阅读
常用的传输层有以下几种:
tsocket —— 使用阻塞式 i/o 进行传输,是最常见的模式
tframedtransport —— 使用非阻塞方式,按块的大小进行传输,类似于 java 中的 nio
tnonblockingtransport —— 使用非阻塞方式,用于构建异步客户端
tserversocket:非阻塞型 socket,用于服务器端,accecpt 到的 socket 类型都是 tsocket(即阻塞型 socket)
以上就是thrift框架快速入门方法的详细内容。
