Thrift跨语言RPC框架
最近入职需要用到Thrift框架(准确来说其实是MTThrift),记录一下学习进度。
RPC?
RPC(Remote Procedure Call,远程过程调用)可以让我们像调用本地一样发起远程调用,为我们屏蔽一些底层细节,例如序列化,编解码,网络传输等。
Thrift
Thrift是一个轻量级、跨语言的远程服务调用框架,最初由Facebook开发,后面进入Apache开源项目。它通过自身的IDL中间语言, 并借助代码生成引擎生成各种主流语言的RPC服务端/客户端模板代码。
Thrift支持多种不同的编程语言,包括C++、Java、Python、PHP、Ruby等,Thrift更多介绍可以参考Apache官网
Thrift的主要特点有:
- 基于二进制的高性能的编解码框架
- 基于NIO的底层通信
- 相对简单的服务调用模型
- 使用IDL支持跨平台调用
IDL
Thirft是一个典型的CS架构,客户端和服务端可以使用不同的语言开发。可以使用一种中间语言关联客户端和服务端的语言,将这种语言称为IDL(Interface Definition Language)。
Thrift采用IDL定义通用的服务接口,然后通过Thrift提供的编译器,将服务接口编译成为不同语言的代码,实现跨语言的功能。IDL详细介绍可以参考apache,IDL文件通常以.thrift结尾。
IDL语法
基本类型
- bool (布尔值(true,false)
- byte (8位有符号整型
- i16 (16位有符号整型
- i32 (32位有符号整型
- i64 (64位有符号整型
- double (64位浮点数
- string (字符串,采用UTF-8编码
特殊类型
struct
struct格式定义如下:
struct <结构体名称> {
<序号> : [字段性质]<字段类型><字段名称> [ = <默认值>] [; or , or ]
}
例如
//required表示该字段在传输过程一定要有,optional表示可以不传该字段,若不传该字段则也不会对该字段进行序列化。
struct User {
1 : required string name;//该字段必须要有
2 : optional i32 age = 0;//该字段可以没有,有默认值0
3 : bool gender,//默认字段类型为optional,末尾可以以逗号结尾,可以以分号结尾,也可以啥也没有
}
注意
- struct不能继承,但是允许嵌套,但不允许自己嵌套自己
- 成员都是有明确类型
- 成员被正整数编号,编好不能重复,为了在传输过程中编码使用
- optional不填充则不会序列化,required必须填充也必须序列化
枚举(enum)
Thrift不支持枚举类嵌套,枚举常量必须是32位的正整数。例如
enum HttpStatus {
OK = 200;
NOTFOUND = 404;
}
容器
IDL中的容器只有三种,分别是list(即C++ STL的vector,Java中的ArrayList),map(C++ STL中的map,Java中的HashMap),set(C++中的set, Java中的HashSet)。使用容器类型时必须指定范性,集合中的元素可以是除了service中的任何类型,包括exception。
Exception
异常在语法和功能上类似结构体,区别是异常使用关键字exception,而且异常是继承每种语言的异常基础类。例如
exception MyException {
1 : i32 errorcode;
2 : string meg;
}
service ExampleService {
string GetName() throw (1 : MyService e)
}
Service
服务的定义方法等同于面向对象的接口,例如
service HelloService {
i32 sayInt(1 : i32 param);
string sayString(1 : string param);
bool sayBool(1 : bool param);
}
命名空间(namespace)
Thrift的命名空间类似于C++中的namespace和Java中的package,他们提供了一个组织(隔离)代码的简便方式,命名空间也可以解决类型定义中的命名冲突。
namespace java com.example.test //生成Java代码
namespace cpp com.example.test //生成cpp代码
编译
编译器安装
参考官方文档
编译命令
# 生成Java代码
thrift -gen java user.thrift
# 生成C++代码
thrift -gen cpp user.thrift
生成其他语言的命令可以自行去如前所述apache官网查看~