Thrift支持多种不同的编程措辞,包括C++、Java、Python、PHP、Ruby等,本系列紧张讲述基于Java措辞的Thrift的配置办法和详细利用。
正文Thrift的技能栈
Thrift对软件栈的定义非常的清晰, 使得各个组件能够疏松的耦合, 针对不同的运用处景, 选择不同是办法去搭建做事。

Thrift软件栈分层从下向上分别为:传输层(Transport Layer)、协议层(Protocol Layer)、处理层(Processor Layer)和做事层(Server Layer)。
传输层(Transport Layer):传输层卖力直接从网络中读取和写入数据,它定义了详细的网络传输协议;比如说TCP/IP传输等。协议层(Protocol Layer):协议层定义了数据传输格式,卖力网络传输数据的序列化和反序列化;比如说JSON、XML、二进制数据等。处理层(Processor Layer):处理层是由详细的IDL(接口描述措辞)天生的,封装了详细的底层网络传输和序列化办法,并委托给用户实现的Handler进行处理。做事层(Server Layer):整合上述组件,供应详细的网络线程/IO做事模型,形成终极的做事。Thrift的特性
(一) 开拓速率快
通过编写RPC接口Thrift IDL文件,利用编译天生器自动天生做事端骨架(Skeletons)和客户端桩(Stubs)。从而省去开拓者自定义和掩护接口编解码、传输、做事器多线程模型等根本事情。
做事端:只须要按照做事骨架即接口,编写好详细的业务处理程序(Handler)即实现类即可。客户端:只须要拷贝IDL定义好的客户端桩和做事工具,然后就像调用本地工具的方法一样调用远端做事。(二) 接口掩护大略
通过掩护Thrift格式的IDL(接口描述措辞)文件(把稳写好注释),即可作为给Client利用的接口文档利用,也自动天生接口代码,始终保持代码和文档的同等性。且Thrift协议可灵巧支持接口的可扩展性。
(三) 学习本钱低
由于其来自Google Protobuf开拓团队,以是其IDL文件风格类似Google Protobuf,且更加易读易懂;特殊是RPC做事接口的风格就像写一个面向工具的Class一样大略。
初学者只需参照:http://thrift.apache.org/,一个多小时就可以理解Thrift IDL文件的语法利用。
(四) 多措辞/跨措辞支持
Thrift支持C++、 Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk等多种措辞,即可天生上述措辞的做事器端和客户端程序。
对付我们常常利用的Java、PHP、Python、C++支持良好,虽然对iOS环境的Objective-C(Cocoa)支持稍逊,但也完备知足我们的利用哀求。
(五) 稳定/广泛利用
Thrift在很多开源项目中已经被验证是稳定和高效的,例如Cassandra、Hadoop、HBase等;国外在Facebook中有广泛利用,海内包括百度、美团小米、和饿了么等公司。
Thrift的数据类型
Thrift 脚本可定义的数据类型包括以下几种类型:
基本类型:bool: 布尔值byte: 8位有符号整数i16: 16位有符号整数i32: 32位有符号整数i64: 64位有符号整数double: 64位浮点数string: UTF-8编码的字符串binary: 二进制串构造体类型:struct: 定义的构造体工具容器类型:list: 有序元素列表set: 无序无重复元素凑集map: 有序的key/value凑集非常类型:exception: 非常类型做事类型:service: 详细对应做事的类Thrift的协议
Thrift可以让用户选择客户端与做事端之间传输通信协议的种别,在传输协议上总体划分为文本(text)和二进制(binary)传输协议。为节约带宽,提高传输效率,一样平常情形下利用二进制类型的传输协议为多数,有时还会利用基于文本类型的协议,这须要根据项目/产品中的实际需求。常用协议有以下几种:
TBinaryProtocol:二进制编码格式进行数据传输TCompactProtocol:高效率的、密集的二进制编码格式进行数据传输TJSONProtocol: 利用JSON文本的数据编码协议进行数据传输TSimpleJSONProtocol:只供应JSON只写的协议,适用于通过脚本措辞解析Thrift的传输层
常用的传输层有以下几种:
TSocket:利用壅塞式I/O进行传输,是最常见的模式TNonblockingTransport:利用非壅塞办法,用于构建异步客户端TFramedTransport:利用非壅塞办法,按块的大小进行传输,类似于Java中的NIOThrift的做事端类型
TSimpleServer:单线程做事器端,利用标准的壅塞式I/OTThreadPoolServer:多线程做事器端,利用标准的壅塞式I/OTNonblockingServer:单线程做事器端,利用非壅塞式I/OTHsHaServer:半同步半异步做事器端,基于非壅塞式IO读写和多线程事情任务处理TThreadedSelectorServer:多线程选择器做事器端,对THsHaServer在异步IO模型上进行增强Thrift入门示例
(一) 编写Thrift IDL文件
a). 下载0.10.0的Thrift IDL编译器,下载地址:http://thrift.apache.org/docs/install。 通过编译天生器天生.java接口的类文件。
b). 下载Windows安装环境的.exe文件,将thrift.exe的路径加入环境变量中。在Idea上安装Thrift编辑插件。
c). 编写hello.thrift的IDL文件:
service HelloWorldService {
string say(1: string username)
}
d). 利用代码天生工具天生代码,实行以下命令:
thrift -gen java hello.thrift
e). 由于未指定代码天生的目标目录,天生的类文件默认存放在gen-java目录下。这里天生一个HelloWorldService.java类文件,文件大小超过数千行,下面截取一部分核心代码。
public class HelloWorldService {
public interface Iface {
public String say(String username) throws org.apache.thrift.TException;
}
public interface AsyncIface {
public void say(String username, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws org.apache.thrift.TException;
}
public static class Client extends org.apache.thrift.TServiceClient implements Iface {
public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
public Factory() {
}
public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
return new Client(prot);
}
public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
return new Client(iprot, oprot);
}
}
public Client(org.apache.thrift.protocol.TProtocol prot) {
super(prot, prot);
}
public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
super(iprot, oprot);
}
public String say(String username) throws org.apache.thrift.TException {
send_say(username);
return recv_say();
}
// 省略.....
}
public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
private org.apache.thrift.async.TAsyncClientManager clientManager;
private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
this.clientManager = clientManager;
this.protocolFactory = protocolFactory;
}
public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
return new AsyncClient(protocolFactory, clientManager, transport);
}
}
public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
super(protocolFactory, clientManager, transport);
}
public void say(String username, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws org.apache.thrift.TException {
checkReady();
say_call method_call = new say_call(username, resultHandler, this, ___protocolFactory, ___transport);
this.___currentMethod = method_call;
___manager.call(method_call);
}
// 省略.....
}
// 省略.....
}
对付开拓职员而言,利用原生的Thrift框架,仅须要关注以下四个核心内部接口/类:Iface, AsyncIface, Client和AsyncClient。
Iface:做事端通过实现HelloWorldService.Iface接口,向客户真个供应详细的同步业务逻辑。AsyncIface:做事端通过实现HelloWorldService.Iface接口,向客户真个供应详细的异步业务逻辑。Client:客户端通过HelloWorldService.Client的实例工具,以同步的办法访问做事端供应的做事方法。AsyncClient:客户端通过HelloWorldService.AsyncClient的实例工具,以异步的办法访问做事端供应的做事方法。(二) 新建Maven工程
a). 新建maven工程,引入thrift的依赖,这里利用的是版本0.10.0。
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.10.0</version>
</dependency>
b). 将天生类的HelloWorldService.java源文件拷贝进项目源文件目录中,并实现HelloWorldService.Iface的定义的say()方法。
HelloWorldServiceImpl.java
public class HelloWorldServiceImpl implements HelloWorldService.Iface {
@Override
public String say(String username) throws TException {
return \"大众Hello \"大众 + username;
}
}
c). 做事器端程序编写:
SimpleServer.java
public class SimpleServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(ServerConfig.SERVER_PORT);
TServerSocket serverTransport = new TServerSocket(serverSocket);
HelloWorldService.Processor processor =
new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());
TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
TSimpleServer.Args tArgs = new TSimpleServer.Args(serverTransport);
tArgs.processor(processor);
tArgs.protocolFactory(protocolFactory);
// 大略的单线程做事模型 一样平常用于测试
TServer tServer = new TSimpleServer(tArgs);
System.out.println(\"大众Running Simple Server\"大众);
tServer.serve();
}
}
d). 客户端程序编写:
SimpleClient.java
public class SimpleClient {
public static void main(String[] args) {
TTransport transport = null;
try {
transport = new TSocket(ServerConfig.SERVER_IP, ServerConfig.SERVER_PORT, ServerConfig.TIMEOUT);
TProtocol protocol = new TBinaryProtocol(transport);
HelloWorldService.Client client = new HelloWorldService.Client(protocol);
transport.open();
String result = client.say(\公众Leo\"大众);
System.out.println(\"大众Result =: \"大众 + result);
} catch (TException e) {
e.printStackTrace();
} finally {
if (null != transport) {
transport.close();
}
}
}
}
e). 运行做事端程序,做事端在指定端口监听客户真个连接要求,掌握台输出启动日志:
image
f). 运行客户端程序,客户端通过网络要求HelloWorldService的say()方法的详细实现,掌握台输出返回结果:
这里利用的一个基于单线程同步的大略做事模型,一样平常仅用于入门学习和测试!
本文对Thrift的观点做了干系先容,体验了一番thrift程序如何编写!