要使用的时候首先应该先编辑一个thrift文件,其中包括结构体和服务的定义。
结构的定义
struct User{
1:required string userId
2:required i64 balance
3:optinal string name
}
如果变量有默认值,可以直接写在定义文件里:
struct User {
1: strubg uid
2: i64 balance = 0
3: map<i16,string> map
}
-
基本类型(括号内为对应的Java类型):
- bool(boolean): 布尔类型(TRUE or FALSE)
- byte(byte): 8位带符号整数
- i16(short): 16位带符号整数
- i32(int): 32位带符号整数
- i64(long): 64位带符号整数
- double(double): 64位浮点数
- string(String): 采用UTF-8编码的字符串
-
除了上面提到的基本数据类型,Thrift还支持以下容器类型:
- list(java.util.ArrayList)
- set(java.util.HashSet)
- map(java.util.HashMap)
服务的定义
include "helloworld.thrift"
namespace java com.core
service Base{
string helloworld()
}
service Core{
string transfer(1:string fromId,2:string toId, 3:i64 amount)
int64 add(1:i64 number1,2:i64 number2)
}
在这个core.thrift文件里定义的Core这个service继承了Base这个service,其中namespace决定了生成的java文件将会放在哪个包内。
服务的实现
如果要单独生成某个thrift文件的指定语言版本代码,输入以下命令
thrift --gen <language> <Thrift filename>
如果要递归地将其include的thrift文件也生成,则使用如下命令
thrift -r --gen <language> <Thrift filename>
对于上面所示的文件,使用的命令为 thrift --gen java core.thrift
则会生成一个文件名为Core的文件,此文件中有一个为Iface的接口,实现此接口必须实现thrift文件里定义的方法。其他内容是为了thrift能正常调用的逻辑,这个文件不能进行修改。
在实际使用中,新建一个类名为CoreImpl实现Core.Iface,在这里我们将实现transfer和add两个方法的具体逻辑。这样就已经写完了thrift调用服务的准备工作,下面涉及到如何启动服务和调用服务。
服务的启动
传输通信协议
Thrift 可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本 (text) 和二进制 (binary) 传输协议,为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数,有时还会使用基于文本类型的协议,这需要根据项目 / 产品中的实际需求。常用协议有以下几种:
- TBinaryProtocol —— 二进制编码格式进行数据传输
- TCompactProtocol —— 高效率的、密集的二进制编码格式进行数据传输
- TJSONProtocol —— 使用 JSON 的数据编码协议进行数据传输
- TSimpleJSONProtocol —— 只提供 JSON 只写的协议,适用于通过脚本语言解析
服务端和客户端必须使用同一种传输通信协议
传输层
常用的传输层有以下几种:
- TSocket —— 使用阻塞式 I/O 进行传输,是最常见的模式,使用TServerSocket
- TFramedTransport —— 使用非阻塞方式,按块的大小进行传输,类似于 Java 中的 NIO,使用TNonblockingServerTransport
- TNonblockingTransport —— 使用非阻塞方式,用于构建异步客户端
服务端类型
常见的服务端类型有以下几种:
- TSimpleServer —— 单线程服务器端使用标准的阻塞式 I/O
- TThreadPoolServer —— 多线程服务器端使用标准的阻塞式 I/O
- TNonblockingServer —— 多线程服务器端使用非阻塞式 I/O
Server与Client
下面是简单的使用TBinaryProtocol通信和使用Tsocket以及服务端类型为TThreadPoolServer的情况:
Core的Server
public static void main(String[] args) {
try {
TServerSocket serverTransport = new TServerSocket(9999); //设置服务端口
Factory proFactory = new TBinaryProtocol.Factory(); //设置通信协议
TProcessor processor = new Core.Processor<Core.Iface>(CoreImpl); //关联处理器服务
TThreadPoolServer.Args serverArgs = (new TThreadPoolServer.Args(serverTransport)).processor(processor);
serverArgs.protocolFactory(proFactory);//填充启动参数
TServer server = new TThreadPoolServer(serverArgs);
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
Core的Client
public static void main(String[] args) {
try {
TTransport transport = new TSocket("localhost", 9999);
transport.open();
TProtocol protocol = new TBinaryProtocol(transport);//设置传输协议
Core.Client client = new Core.Client(protocol);
client.transfer("1","2",1);
transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
}
}
非阻塞式异步
to be continue