thrift是一个支持多语言进行RPC的软件库,开发者通过定义数据类型和服务接口,经由thrift的代码生成引擎就可以构建RPC客户端和服务端所需要的代码。它的核心组件如下:
-
Types。thrift支持的数据类型,由thrift自身定义,定义的类型是所有编程语言中都会用到的关键类型
-
Transport。做数据传输用,抽象了对网络的一些操作,比如 read/write
-
Protocol。数据经由client和server进行编码或者解码的格式,比如 JSON、binary
-
Versioning。client和server对于接口变动的处理方式,比如server在旧接口上新增了一个字段,但是client还是旧的
-
Processors。服务端收到RPC后的处理逻辑,负责将读到的内容交由server处理,并将结果写回输出流
Type
-
支持的基本类型为
-
bool 取值为true/false
-
byte 有符号的1个字节
-
i16 16比特的有符号integer
-
i32 32比特的有符号integer
-
i64 64比特的有符号integer
-
double 64比特的浮点数
-
string 文本字符串
-
-
复杂类型,比如java中的自定义对象,可以通过 struct 来组织
-
集合目前支持 list/set/map,可以对应成java的ArrayList/HashSet/HashMap
-
异常通过 exception 来标识,类似 struct
-
接口定义使用 service 来标识
-
枚举使用 enum 来标识
Thrift接口描述语言(IDL)
Thrift IDL文件是开发者自定义逻辑内容的地方,它会被Thrift 的代码生成器处理成目标语言的代码
以下以java来类比
-
namespace java paxi.maokitty.verify.service
namespace 相当于java中声明了当前文件的包名,java则是表示namespace的适用语言 -
include 'myException.thrift'
include相当于import,引入别的包,以便使用它的内容 -
typedef myException.myException myException
定义别名,方便写 -
1:i32 code
定义字段 code,类型是i32,序号是1 -
string say(1:string msg)throws(1:myException e)
定义方法say,返回值是string,参数是string,抛出自定义异常 myException(这里是别名)
Transport
-
TTransport 提供了一些网络方法的抽象 open/close/read/write/flush ;
-
TServerTransport 则是负责接受创建连接 open/listen/accept/close
-
TSocket 对TTransport的集成实现,提供sokcet
Protocol
protocol提供了一种将内存数据映射到一种特定结构的机制,thrift的设计是要支持流式协议
-
数据整个被编码成一系列的字段,每个字段都有一个类型和一个唯一的识别码(序号)
-
structs的结束则会自带一个 STOP 的标记
这种设计方式使得thrift协议能够自我界定,而不需要关心具体的编码方式
当然如果固定格式是一种优势或者流处理不是必须的,可以使用TFrameTransport来支持
Versioning
Versioning在thrift中的实现是通过字段识别码完成的,每个声明的字段前面都会有一个唯一的字段识别码
如果没有人为的添加,thrift自身会从-1开始递减,自动加上
当Server读到数据之后,会根据字段识别码来识别是否有根据定义文件存放了这个字段,如果没有,就会跳过无法识别字段的长度,而不用抛出异常。如果这个字段是有的,而且必须要的,则在真的使用这个字段前,先通过isset检查是否真的存在
新老版本可能存在的情况分析
-
添加了新的字段,老的客户端,新的server。此时老的客户端不会发送新的字段,新的server发现字段没有set,就按照过期请求的默认行为处理
-
删除了字段,老的客户端,新的server。老的客户端会发送已经删掉的字段,新的server会直接无视
-
添加了新的字段,新的客户端,老的server。新客户端会发送新的字段,老的server则是直接无视这个字段,按现有逻辑处理
-
删了字段,新的客户端,老的server。建议不要出现这种情况
Processor
对每个service,都会对应的生成一个Processor,它主要是负责从网络得到的数据中提取出内容,然后代理请求真正的方法,再把结果写入输出的Prococol
thrift命令使用
thrift -out ../src/main/java --gen java:private-members ./myException.thrift
复制代码
-out
指定输出的目录
--gen java:private-members ./myException.thrift
表示目标语言是java,字段使用private
thrift代码
根据thrift的IDL语法,写下自己要实现的函数功能