了解Thrift全貌
来源:互联网 发布:网络运营主管 编辑:程序博客网 时间:2024/05/10 15:18
1.1前言
Apache Thrift是Facebook实现的一种高效的、跨语言的服务部署框架。最初由Facebook于2007年开发,2008年进入Apache开源项目。Thrift通过一个中间语言(IDL, 接口定义语言)来定义RPC的接口和数据类型,然后通过一个编译器生成不同语言的代码(目前支持As3,C Glib,C++,CSharp,D,Delphi,Erlang,Go,Haskell,Java,Java Me,Javascript,Node.js,Objective-c,OCaml, Perl,PHP,Python,Ruby,Smalltalk),并由生成的代码负责RPC协议层和传输层的实现。
1.2架构
Thrift实际上是实现了C/S模式,通过代码生成工具将接口定义文件生成服务器端和客户端代码(可以为不同语言),从而实现服务端和客户端跨语言的支持。用户在Thirft描述文件中声明自己的服务,这些服务经过编译后会生成相应语言的代码文件,然后用户实现服务(客户端调用服务,服务器端提供服务)便可以了。其中protocol(协议层, 定义数据传输格式,可以为二进制或者XML等)和transport(传输层,定义数据传输方式,可以为TCP/IP传输,内存共享或者文件共享等)被用作运行时库。
1.2.1传输方式(Transport)
Transport层提供了一个简单的网络读写抽象层。这使得Thrift底层的transport从系统其它部分(如序列化/反序列化)解耦。以下是一些Transport接口提供的方法:
- open
- close
- read
- write
- flush
除了以上几个接口,Thrift使用ServerTransport接口接受或者创建原始transport对象。正如名字暗示的那样,ServerTransport用在server端,为到来的连接创建Transport对象。ServerTransport提供的方法有:
- listen
- accept
- close
常用的传输方式有以下几种:
- TSocket——阻塞式socket。
- TFramedTransport——使用非阻塞方式,按块的大小进行传输,类似于 Java中的NIO若使用TFramedTransport传输层,其服务器必须为非阻塞的服务类型。
- TFileTransport——以文件形式进行传输。
- TMemoryInputTransport——将内存用于I/O。Java实现时内部实际使用了简单的ByteArrayOutputStream。
- TNonblockingTransport——使用非阻塞方式,用于构建异步客户端。
1.2.2协议(Protocol)
Protocol抽象层定义了一种将内存中数据结构映射成可传输格式的机制。换句话说,Protocol定义了datatype怎样使用底层的Transport对自己进行编解码。因此,Protocol的实现要给出编码机制并负责对数据进行序列化。
Thrift可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本 (text) 和二进制 (binary) 传输协议,为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数,有时还会使用基于文本类型的协议,这需要根据项目/产品中的实际需求。常用协议有以下几种:
- TBinaryProtocol ——二进制编码格式进行数据传输。
- TCompactProtocol——高效率的、压缩的二进制编码格式进行数据传输。
- TJSONProtocol——使用JSON的数据编码协议进行数据传输。
- TSimpleJSONProtocol——提供JSON只写协议, 适用于通过脚本语言解析。
1.2.3处理器(Processor)
Processor封装了从输入数据流中读数据和向数据数据流中写数据的操作。读写数据流用Protocol对象表示。Processor的结构体非常简单:
interface TProcessor { bool process(TProtocol in, TProtocol out) throws TException}与服务相关的Processor实现由编译器产生。Processor主要工作流程如下:从连接中读取数据(使用输入protocol),将处理授权给handler(由用户实现),最后将结果写到连接上(使用输出protocol)。
1.2.4服务类型
Server将以上所有特性集成在一起:
(1)创建一个transport对象。
(2)为transport对象创建输入输出protocol。
(3)基于输入输出protocol创建processor。
(4)等待连接请求并将之交给processor处理。
常用的Server有:
- TSimpleServer——简单的单线程服务模型,常用于测试。
- TThreadPoolServer——多线程服务模型,使用标准的阻塞式IO。
- TNonblockingServer——多线程服务模型,使用非阻塞式IO。
第2章Thrift类型
2.1基本类型
- bool:布尔值,true或false,对应Java的boolean。
- byte:8位有符号整数,对应Java的byte。
- i16:16位有符号整数,对应Java的short。
- i32:32位有符号整数,对应Java的int。
- i64:64位有符号整数,对应Java的long。
- double:64位浮点数,对应Java的double。
- string:utf-8编码的字符串,对应Java的String。
2.2特殊类型
- binary:未编码的字节序列,对应Java的ByteBuffer。
2.3结构体类型
- struct:定义公共的对象,类似于C语言中的结构体定义,在Java中是一个 JavaBean。
2.4容器类型
- list:对应Java的ArrayList。
- set:对应Java的HashSet。
- map:对应Java的HashMap。
2.5异常类型
- exception:对应Java的Exception。
2.6服务类型
- service:对应服务的类。
第3章Thrift实例
3.1生成Thrift代码
3.1.1编写Thrift文件
创建一个简单的服务Hello。首先根据Thrift的语法规范编写脚本文件 Hello.thrift,代码如下:
namespace java com.joyveb.demo
serviceHello{
string helloString(1:string para)
i32 helloInt(1:i32 para)
}
其中定义了Hello服务的2个方法,每个方法包含一个方法名,参数列表和返回类型。每个参数包括参数序号,参数类型以及参数名。Thrift是对IDL(Interface Definition Language) 描述性语言的一种具体实现。因此,以上的服务描述文件使用 IDL 语法编写。
3.1.2代码生成
- 在Thrift官网下载Thrift编译器(windows下现为thrift-0.9.2.exe)。
- 将Thrift文件和Thrift编译器放到同一目录(方便编译),在cmd命令提示符中进入该目录,执行:
thrift-0.9.0 --gen java Hello.thrift
编译完成后,会在同目录下的gen-java文件夹下生成相应的Hello.java文件。该文件包含了在 Hello.thrift 文件中描述的服务 Hello 的接口定义,即Hello.Iface接口,以及服务调用的底层通信细节,包括客户端的调用逻辑Hello.Client以及服务器端的处理逻辑 Hello.Processor,用于构建客户端和服务器端的功能。
3.2服务端
将生成的代码copy到自己的工程下,如果工程是maven构建的,在pom.xml文件中添加:
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.0</version>
</dependency>
- 实现服务处理接口:创建HelloImpl.java文件并实现Hello.java文件中的Hello.Iface接口,代码如下:
- 创建TProcessor。
- 创建TServerTransport。
- 创建TProtocol。
- 创建TServer。
- 启动Server。
服务端代码如下:
public class ServerSimple {public static final int SERVER_PORT = 2013;public void startServer() {try {System.out.println("HelloWorld TSimpleServer start ....");TProcessor tprocessor = new Hello.Processor<Hello.Iface>(new HelloImpl());// 简单的单线程服务模型,一般用于测试TServerSocket serverTransport = new TServerSocket(SERVER_PORT);TServer.Args tArgs = new TServer.Args(serverTransport);tArgs.processor(tprocessor);tArgs.protocolFactory(new TBinaryProtocol.Factory());// tArgs.protocolFactory(new TCompactProtocol.Factory());// tArgs.protocolFactory(new TJSONProtocol.Factory());TServer server = new TSimpleServer(tArgs);server.serve();} catch (Exception e) {System.out.println("Server start error!!!");e.printStackTrace();}}public static void main(String[] args) {ServerSimple server = new ServerSimple();server.startServer();}}服务端序列图如下:
3.3客户端
- 创建Transport。
- 创建TProtocol。
- 基于TTransport和TProtocol创建Client。
- 调用Client的相应方法。
对应客户端代码如下:
public class ClientSimple {public static final String SERVER_IP = "localhost";public static final int SERVER_PORT = 2013;public static final int TIMEOUT = 30000;public void startClient(String userName) {TTransport transport = null;try {transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);// 协议要和服务端一致TProtocol protocol = new TBinaryProtocol(transport);Hello.Client client = new Hello.Client(protocol);transport.open();String result = client.helloString(userName);System.out.println("Thrify client result =: " + result);} catch (TTransportException e) {e.printStackTrace();} catch (TException e) {e.printStackTrace();} finally {if (null != transport) {transport.close();}}}public static void main(String[] args) {ClientSimple client = new ClientSimple();client.startClient("Michael");}}
客户端序列图如下:
注意:客户端和服务端的协议要一致。
第4章参考资料
- Apache Thrift 官网:Thrift源码和使用说明等
- Thrift入门及Java实例演示:Thrift入门很好的参考
- Thrift框架介绍
- Thrift使用指南
- 使用ThriftRPC编写程序
- 浅谈Thrift内部实现原理
- ApacheThrift - 可伸缩的跨语言服务开发框架
- 了解Thrift全貌
- 一个让你了解手机产业链全貌的PPT
- 由浅入深了解Thrift(二)——Thrift工作原理
- Thrift了解4:C#通过Thrift操作HBase实战
- 由浅入深了解Thrift(二)——Thrift工作原理
- java的几种技术规范(可以概括的了解java的全貌)
- 文章解析整理:《入门必看:万字长文带你轻松了解LSTM全貌》
- 从浅到深了解Thrift(一)
- 从浅到深了解Thrift(二)
- 从浅到深了解Thrift(三)
- 测试全貌
- 全貌概览
- django全貌
- defer全貌
- 由浅入深了解Thrift(一)——Thrift介绍与用法
- 由浅入深了解Thrift(三)——Thrift server端的几种工作模式分析
- 由浅入深了解Thrift(三)——Thrift server端的几种工作模式分析
- 由浅入深了解Thrift(三)——Thrift server端的几种工作模式分析
- 随想录(程序员和收入)
- 去除背景
- 老生常谈:面试算法有必要吗?
- 成长,没你想象的那么迫切
- #、##和__VA_ARGS__
- 了解Thrift全貌
- ASP.NET MVC中Action返回值类型
- Activity的跳转与传值 startActivity,onActivityResult,setResult
- UVa 10003 - Cutting Sticks
- 三元运算符的类型转换
- tomcat 开启Gzip
- /dev/null 2>&1 详解
- activity嵌套调用问题
- android 获取系统当前时间