Thrift是由Facebook开发的,现由Apache管理的开源RPC框架。Thrift作为接口描述语言,被用于定义和创建跨语言的服务。通过代码生成引擎封装了不同语言间IO、网络传输的细节,以创建无缝的跨平台、跨语言服务。
用法
语法
说到一门语言必然要提到它的语法。Thrift作为一种通用的IDL,其语法格式较为简单,不仅提供了绝大多数语言的函数声明格式、基本类型,同时也对不同语言的特点提供了不同的特性。
基本类型
bool: true/false
byte: 8 位有符号整数
i16:16 位有符号整数
i32:32 位有符号整数
i64:64 位有符号整数
double:64 位浮点数
string:字符串
Typedef
用法类似于CPP,支持了类型别名。如:typedef i32 int。
enum
与大多数语言的枚举是一个目的。但是Thrift中Enum只支持整数值。如下:
enum Fruit {
Apple = 1,
Banana = 2,
Cherry = 3,
}
Struct/Union
需要注意的是Thrift并不直接使用基本类型(建议这样使用,良好的语义在团队开发中可以起到重要的作用),我们往往会针对不同的接口设计独立的结构体。Union则是针对特定语言的结构,使用方式与struct类似。如:
struct EchoRequest {
1: string message
}
struct EchoResponse {
1: string message
}
在struct后紧跟类型名以及{},括号内是各成员的类型及名称,称为域,每行之间以逗号分开。域前有正整数标识符,可以不连续,但一经定义,最好不要修改,否则可能会导致新旧代码所生成的接口参数顺序的不同,导致兼容性问题。
之后则是域的限定,由required/optional修饰。
其中,若以required修饰的,则在后面的构造中必须赋值,否则会认为异常。
容器
Thrift提供了三种容器,分别是list,set,map。
如:list<T>,其中,T为任意类型。
需要注意的是,一方面某些语言不支持容器中有复杂类型,另一方面Thrift对复杂类型的解析可能会出错。所以容器中最好使用基本类型。
异常
用法与struct类似,是为异常处理专门设计的。
Header
一个Thrift文件可以包含任意多个(包括0个)Header。它描述了这个接口所引用的库、命名空间等文件。如:Include,CppInclude,Namespace等。其中Include只是简单地引入了其他Thrift文件的内容;CppInlcude则表示在生成的CPP文件中包含所引用的CPP文件;NameSpace组织了代码,可以简单的认为对不同语言的分类处理。
注释
兼容(缝)了许多类型的注释。如:
//这是注释
/*这也是注释*/
#这还是注释
服务(service)
接口定义是thrift的一大重点。它实质上是一个包含函数名的列表。定义服务时,先以service开头,再接服务名,然后是一对花括号。
内部则是一个个接口的定义,以 返回值 接口名(参数编号:参数 参数名,...) 异常 为格式。如:
serivce EchoService{
EchoResponse echo(1: EchoRquest msg) throw (1: error err)
}
注意到,每次只能返回一个变量。异常是可选的。
代码生成
使用Thrift提供的代码生成工具,同时也可以使用Kitex进行go的生成。如
thrift --gen cpp echo.thrift
架构
Thrift采用了典型的C/S架构。通过上述部分来关联客户端和服务端。
(图片来源于网络)
整体架构可以分为5层。
业务逻辑
服务,包含对应服务及依赖
TProtocol,协议层
TTransports,传输层
I/O传输。