跨平台通信中间件thrift学习【Java版本】(转)

摘要:
转移自: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.Whatisthrift ? 节俭是一个跨语言服务部门

转自: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学习【Java版本】(转)第1张
跨平台通信中间件thrift学习【Java版本】(转)第1张
 
如图所示,图中黄色部分是用户实现的业务逻辑,褐色部分是根据 Thrift 定义的服务接口描述文件生成的客户端和服务器端代码框架,红色部分是根据 Thrift 文件生成代码实现数据的读写操作。红色部分以下是 Thrift 的传输体系、协议以及底层 I/O 通信,使用 Thrift 可以很方便的定义一个服务并且选择不同的传输协议和传输层而不用重新生成代码。
 
Thrift 服务器包含用于绑定协议和传输层的基础架构,它提供阻塞、非阻塞、单线程和多线程的模式运行在服务器上,可以配合服务器 / 容器一起运行,可以和现有的 J2EE 服务器 /Web 容器无缝的结合。
 
5. 安装
http://thrift.apache.org/ 官网下载,需要用ant编译成lib,最终实际项目中只需要加入如下jar包:
* 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”。

免责声明:文章转载自《跨平台通信中间件thrift学习【Java版本】(转)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mockito使用用javascript实现禁止页面后退返回上一页的代码下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux服务器的Gzip文件压缩方法[转]

一、gzip介绍          gzip是GNU zip的缩写,它是一个GNU自由软件的文件压缩程序,也经常用来表示gzip这种文件格式。软件的作者是Jean-loup Gailly和Mark Adler。1992年10月31日第一次公开发布,版本号是0.1,目前的稳定版本是1.2.4。         Gzip主要用于Unix系统的文件压缩。我们在L...

5G名词术语

英文缩写  说明   VR(Virtual Reality) 虚拟现实   VLOG(Video blog) 视频网络日志   AR(Augmented Reality) 增强   MR(Mixed Reality) 混合现实    SON(self-organizing network)  自组织网络   CDN(c...

java nio--采用Selector实现Socket通信

server: 1 /** 2 * 选择器服务端 3 * Created by ascend on 2017/6/9 9:30. 4 */ 5 public class SelectorServer { 6 // public final static String REMOTE_IP = "192.168.0....

JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。 1 byte checksum CRC-16 CRC-16 (Modbus)CRC-16 (Sick)CRC-CCITT (XModem)CRC-CCITT (0xFFFF) CRC-CCITT...

Windows phone 8 学习笔记(3) 通信(转)

Windows phone 8 可利用的数据通信方式比较广泛,在硬件支持的前提下,我们可以利用WiFi、蓝牙、临近感应等多种方式。数据交互一般通过套接字来完成,我们将在本文详细的分析。 快速导航:一、WP8套接字二、蓝牙三、NFC四、获取网络状态五、访问web的几种方式 一、WP8套接字 1)创建套接字客户端 Windows phone 8中的套接字并...

poi读取word2003(.doc文档)中的表格

poi读取word2003(.doc文档)中的表格 Jakarta POI 是apache的子项目,目标是处理ole2对象。它提供了一组操纵Windows文档的Java API。在网上见到好多通过poi读取excel的文章,读写也很方便,和jxl有的一比。在这里,主要是poi对word中的表格数据读取。 具体见代码 1 import java.io.Fi...