转自:http://neoremind.com/2012/03/%E8%B7%A8%E5%B9%B3%E5%8F%B0%E9%80%9A%E4%BF%A1%E4%B8%AD%E9%97%B4%E4%BB%B6thrift%E5%AD%A6%E4%B9%A0%E3%80%90java%E7%89%88%E6%9C%AC%E3%80%91/
1. What is thrift?
Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目。跨平台通信中thrift可以作为二进制的高性能的通讯中间件,支持数据(对象)序列化和多种类型的RPC服务。
2. thrift为我们做了什么?
首先我们需要先了解下任何RPC的解决方案都包含如下几层实现:
· 服务层(service):RPC接口定义与实现
· 协议层(protocol):RPC报文格式和数据编码格式
· 传输层(transport):实现底层的通信(如 socket)以及系统相关的功能(如事件循环、多线程)
Thrift通过一个中间语言(IDL, 接口定义语言)来定义RPC的接口和数据类型,然后通过一个编译器生成不同语言的代码(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk等),并由生成的代码负责RPC协议层和传输层的实现。我们只需要去实现具体的接口实现就可以了。
Thrift实际上是实现了请求响应的C/S模式,通过代码生成工具将接口定义文件生成服务器端代码,从而实现服务端和客户端跨语言的支持。用户在Thirft描述文件中声明自己的服务,这些服务经过编译后会生成相应语言的代码文件,然后用户实现服务便可以了。
3. thrift基本概念
数据类型
* Base Types:基本类型
* Struct:结构体类型
* Container:容器类型,即List、Set、Map
* Exception:异常类型
* Service: 定义对象的接口,和一系列方法
协议层类型
Thrift可以让你选择客户端与服务端之间传输通信协议的类别,在传输协议上总体上划分为文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下
使用二进制类型的传输协议为多数,但有时会还是会使用基于文本类型的协议,这需要根据项目/产品中的实际需求:
* TBinaryProtocol – 二进制编码格式进行数据传输。
* TCompactProtocol – 这种协议非常有效的,使用Variable-Length Quantity (VLQ) 编码对数据进行压缩。
* TJSONProtocol – 使用JSON的数据编码协议进行数据传输。
* TSimpleJSONProtocol – 这种节约只提供JSON只写的协议,适用于通过脚本语言解析
* TDebugProtocol – 在开发的过程中帮助开发人员调试用的,以文本的形式展现方便阅读。
传输层类型
* TSocket – 使用堵塞式I/O进行传输,也是最常见的模式。
* THttpTransport – 采用Http传输协议进行数据传输
* TFileTransport – 顾名思义按照文件的方式进程传输,虽然这种方式不提供Java的实现,但是实现起来非常简单。
* TZlibTransport – 使用执行zlib压缩,不提供Java的实现。
下面几个类主要是对上面几个类地装饰(采用了装饰模式),以提高传输效率。
TBufferedTransport – 对某个Transport对象操作的数据进行buffer,即从buffer中读取数据进行传输,或者将数据直接写入buffer
TFramedTransport – 以frame为单位进行传输,非阻塞式服务中使用。同TBufferedTransport类似,也会对相关数据进行buffer,同时,它支持定长数据发送和接收。
TMemoryBuffer – 从一个缓冲区中读写数据,使用内存I/O,就好比Java中的ByteArrayOutputStream实现。
服务端类型
* TSimpleServer– 简单的单线程服务模型,常用于测试
* TThreadedServer – 多线程服务模型,使用阻塞式IO,每个请求创建一个线程。
* TThreadPoolServer – 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
* TNonblockingServer – 多线程服务模型,使用非阻塞式IO(需使用TFramedTransport数据传输方式)
4. Thrift 架构
Thrift 包含一个完整的堆栈结构用于构建客户端和服务器端。下图描绘了Thrift的整体架构。
如图所示,图中黄色部分是用户实现的业务逻辑,褐色部分是根据 Thrift 定义的服务接口描述文件生成的客户端和服务器端代码框架,红色部分是根据 Thrift 文件生成代码实现数据的读写操作。红色部分以下是 Thrift 的传输体系、协议以及底层 I/O 通信,使用 Thrift 可以很方便的定义一个服务并且选择不同的传输协议和传输层而不用重新生成代码。
Thrift 服务器包含用于绑定协议和传输层的基础架构,它提供阻塞、非阻塞、单线程和多线程的模式运行在服务器上,可以配合服务器 / 容器一起运行,可以和现有的 J2EE 服务器 /Web 容器无缝的结合。
5. 安装
* libthrift.jar
* slf4j-api-1.5.8.jar
* slf4j-log4j12-1.5.8.jar
* log4j-1.2.15.jar
6. 简单实例
创建一个简单的Helloworld。首先根据Thrift的语法规范编写脚本文件Hello.thrift,代码如下:
namespace java service.demo
service Hello{
string helloString(1:string para)
i32 helloInt(1:i32 para)
bool helloBoolean(1:bool para)
void helloVoid()
string helloNull()
}
|
其中定义了服务 Hello 的五个方法,每个方法包含一个方法名,参数列表和返回类型。每个参数包括参数序号,参数类型以及参数名。
使用thrift.exe -gen java Hello.thrift生成两个gen-java文件夹,里面就有我们生成的服务器端接口Hello.java了。
创建 HelloServiceImpl.java 文件并实现 Hello.java 文件中的 Hello.Iface 接口,代码如下:
package service.demo;
import org.apache.thrift.TException;
public class HelloServiceImpl implements Hello.Iface {
@Override
public boolean helloBoolean(boolean para) throws TException {
return para;
}
@Override
public int helloInt(int para) throws TException {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return para;
}
@Override
public String helloNull() throws TException {
return null;
}
@Override
public String helloString(String para) throws TException {
return para;
}
@Override
public void helloVoid() throws TException {
System.out.println("Hello World");
}
}
|
创建服务器端实现代码,将 HelloServiceImpl 作为具体的处理器传递给 Thrift 服务器,代码如下:
package service.server;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import service.demo.Hello;
import service.demo.HelloServiceImpl;
public class HelloServiceServer {
/**
* 启动 Thrift 服务器
* @param args
*/
public static void main(String[] args) {
try {
// 设置服务端口为 7911
TServerSocket serverTransport = new TServerSocket(7911);
// 设置协议工厂为 TBinaryProtocol.Factory
Factory proFactory = new TBinaryProtocol.Factory();
// 关联处理器与 Hello 服务的实现
TProcessor processor = new Hello.Processor(new HelloServiceImpl());
TServer server = new TThreadPoolServer(processor, serverTransport,
proFactory);
System.out.println("Start server on port 7911...");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
}
|
创建客户端实现代码,调用 Hello.client 访问服务端的逻辑实现,代码如下:
package service.client;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import service.demo.Hello;
public class HelloServiceClient {
/**
* 调用 Hello 服务
* @param args
*/
public static void main(String[] args) {
try {
// 设置调用的服务地址为本地,端口为 7911
TTransport transport = new TSocket("localhost", 7911);
transport.open();
// 设置传输协议为 TBinaryProtocol
TProtocol protocol = new TBinaryProtocol(transport);
Hello.Client client = new Hello.Client(protocol);
// 调用服务的 helloVoid 方法
client.helloVoid();
transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
}
}
}
|
代码编写完后运行服务器,再启动客户端调用服务 Hello 的方法 helloVoid,在服务器端的控制台窗口输出“Hello World”。
- AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(四):开源的Silverlight运行容器的编译、配置
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(三):配置ActiveXForm运行环境
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(二):配置WinClient分布式运行环境
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- 使用thrift实现了Javaserver和nodejsclient之间的跨平台通信
1. 简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎.以构建在 C++, Java, Python, PHP, Ruby, Erlang ...
- Apache Thrift学习之一(入门及Java实例演示)
目录: 概述 下载配置 基本概念 数据类型 服务端编码基本步骤 客户端编码基本步骤 数据传输协议 实例演示(java) thrift生成代码 实现接口Iface TSimpleServer服务模型 T ...
- Thrift 实现 JAVA,PHP,C#,Python 互相通信
Thrift介绍 https://www.ibm.com/developerworks/cn/java/j-lo-apachethrift/index.html 首先需要下载 Thrift.exe ...
- AgileEAS.NET SOA 中间件平台5.2版本下载、配置学习(一):下载平台并基于直连环境运行
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- [学习日志]2018-11-18 主要: idea更改java版本
idea更改java版本 问题: 解决办法:
- 31天重构学习笔记(java版本)
准备下周分享会的内容,无意间看到.net版本的重构31天,花了两个小时看了下,可以看成是Martin Fowler<重构>的精简版 原文地址:http://www.lostechies.c ...
随机推荐
- JSONModel的基本使用
JSONModel 是一个库,它能智能并且快速的创建出数据 model,你可以在你的 iOS 项目或者 OSX 项目上使用它. 使用前准备 添加 JSONModel 到你的工程中 1.需要的环境: A ...
- 平衡搜索树(二) Rb 红黑树
Rb树简介 红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是Red或Black.通过对任何一条从根到叶子简单 路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍, ...
- mac 下maven的安装
最近在学习mahout,这些安装相关软件的步骤先记下来,避免以后忘记. 1.首先在mac上查看本机的java版本,如果没有需要自己去安装: 我的电脑上安装的java是1.7.0_79 2.在http: ...
- C++中extern关键字使用(转)
参考文章:http://blog.csdn.net/sruru/article/details/7951019 chapter1.如何混合编译C语言和C++ 实际开发过程中,C++中会调用C与语言编写 ...
- OC文件操作(1)
1.文件的浅度遍历与深度遍历: //NSFileManager * fm = [[NSFileManager alloc]init];//创建文件管理器 //第一步创建一个文件管理器 NSError ...
- 《作业控制系列》-“linux命令五分钟系列”之十
本原创文章属于<Linux大棚>博客. 博客地址为http://roclinux.cn. 文章作者为roc 希望您能通过捐款的方式支持Linux大棚博客的运行和发展.请见“关于捐款” == ...
- python - StringIO文本缓冲
参考:http://pymotwcn.readthedocs.org/en/latest/documents/StringIO.html 类StringIO提供了一个在内存中方便处理文本的类文件(读, ...
- centos lnmp 安装笔记
[root@host]# chkconfig nginx on [root@host]# service nginx start [root@host]# service nginx stop [ro ...
- css编译工具Sass中混合宏,继承,占位符分别在什么时候使用
//SCSS中混合宏使用 @mixin mt($var){ margin-top: $var; } .block { @include mt(5px); span { display:block; @ ...
- ASP.NET MVC 过滤器Filter
在Asp.netMvc中当你有以下及类似以下需求时你可以使用Filter功能 判断登录与否或用户权限 决策输出缓存 防盗链 防蜘蛛 本地化与国际化设置 实现动态Action Filter是一种声明式编 ...