现在的位置: 首页 > 综合 > 正文

Thrift入门及Java实例演示 | micmiu – 大大的技术 | 小小的生活

2011年04月29日 ⁄ 综合 ⁄ 共 8676字 ⁄ 字号 评论关闭

Thrift入门及Java实例演示 | micmiu - 大大的技术 | 小小的生活

Thrift入门及Java实例演示

目录:

  • 概述
  • 下载配置
  • 基本概念
    1. 数据类型
    2. 服务端编码基本步骤
    3. 客户端编码基本步骤
    4. 数据传输协议
  • 实例演示(java)
    1.  thrift生成代码
    2.  实现接口Iface
    3. TSimpleServer服务模型
    4. TThreadPoolServer 服务模型
    5. TNonblockingServer 服务模型
    6. THsHaServer服务模型
    7. 异步客户端

[一]、概述

Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。

Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

官网地址:thrift.apache.org

推荐值得一看的文章:

[二]、下载配置

到官网下载最新版本,截止今日(2012-06-11)最新版本为0.8.0.

1. 如果是Maven构建项目的,直接在pom.xml 中添加如下内容:

1 <dependency>
2   <groupId>org.apache.thrift</groupId>
3   <artifactId>libthrift</artifactId>
4   <version>0.8.0</version>
5 </dependency>

2.如果自己编译lib包,把下载的压缩包解压到X:盘,然后在X:\thrift-0.8.0\lib\java 目录下运行ant进行自动编译,会在X:\thrift-0.8.0\lib\java\build\ 目录下看到编译好的lib包:libthrift-0.8.0.jar

[三]、基本概念

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
  • 结构体类型:
    • struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean
  • 容器类型:
    • list:对应 Java 的 ArrayList
    • set:对应 Java 的 HashSet
    • map:对应 Java 的 HashMap
  • 异常类型:
    • exception:对应 Java 的 Exception
  • 服务类型:
    • service:对应服务的类

2.服务端编码基本步骤:

  • 实现服务处理接口impl
  • 创建TProcessor
  • 创建TServerTransport
  • 创建TProtocol
  • 创建TServer
  • 启动Server

3.客户端编码基本步骤:

  • 创建Transport
  • 创建TProtocol
  • 基于TTransport和TProtocol创建 Client
  • 调用Client的相应方法

4.数据传输协议

  • TBinaryProtocol : 二进制格式.
  • TCompactProtocol : 压缩格式
  • TJSONProtocol : JSON格式
  • TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

tips:客户端和服务端的协议要一致

[四]、实例演示

1. thrift生成代码

创建Thrift文件:G:\test\thrift\demoHello.thrift ,内容如下:

1 namespace java com.micmiu.thrift.demo
2  
3 service  HelloWorldService {
4   string sayHello(1:string username)
5 }

目录结构如下:

G:\test\thrift>tree /F
卷 other 的文件夹 PATH 列表
卷序列号为 D238-BE47
G:.
    demoHello.thrift
    demouser.thrift
    thrift-0.8.0.exe

没有子文件夹

thrift-0.8.0.exe 是官网提供的windows下编译工具,运用这个工具生成相关代码:

1 thrift-0.8.0.exe -r -gen java ./demoHello.thrift

生成后的目录结构如下:

G:\test\thrift>tree /F
卷 other 的文件夹 PATH 列表
卷序列号为 D238-BE47
G:.
│  demoHello.thrift
│  demouser.thrift
│  thrift-0.8.0.exe
│
└─gen-java
    └─com
        └─micmiu
            └─thrift
                └─demo
                        HelloWorldService.java

将生成的HelloWorldService.java 文件copy到自己测试的工程中,我的工程是用maven构建的,故在pom.xml中增加如下内容:

1 <dependency>
2     <groupId>org.apache.thrift</groupId>
3     <artifactId>libthrift</artifactId>
4     <version>0.8.0</version>
5 </dependency>
6 <dependency>
7     <groupId>org.slf4j</groupId>
8     <artifactId>slf4j-log4j12</artifactId>
9     <version>1.5.8</version>
10 </dependency>

2. 实现接口Iface

java代码:HelloWorldImpl.java

1 package com.micmiu.thrift.demo;
2  
3 import org.apache.thrift.TException;
4  
5 /**
7  *
8  * @author Michael
9  *
10  */
11 public class HelloWorldImpl implements HelloWorldService.Iface {
12  
13     public HelloWorldImpl() {
14     }
15  
16     @Override
17     public String sayHello(String username) throws TException {
18         return "Hi," + username + " welcome to my blog www.micmiu.com";
19     }
20  
21 }

3.TSimpleServer服务端

简单的单线程服务模型,一般用于测试。

编写服务端server代码:HelloServerDemo.java

1 package com.micmiu.thrift.demo;
2  
3 import org.apache.thrift.TProcessor;
4 import org.apache.thrift.protocol.TBinaryProtocol;
5 import org.apache.thrift.protocol.TCompactProtocol;
6 import org.apache.thrift.protocol.TJSONProtocol;
7 import org.apache.thrift.protocol.TSimpleJSONProtocol;
8 import org.apache.thrift.server.TServer;
9 import org.apache.thrift.server.TSimpleServer;
10 import org.apache.thrift.transport.TServerSocket;
11  
12 /**
13  * blog http://www.micmiu.com
14  *
15  * @author Michael
16  *
17  */
18 public class HelloServerDemo {
19     public static final int SERVER_PORT = 8090;
20  
21     public void startServer() {
22         try {
23             System.out.println("HelloWorld TSimpleServer start ....");
24  
25             TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
26                     new HelloWorldImpl());
27             // HelloWorldService.Processor<HelloWorldService.Iface> tprocessor =
28             // new HelloWorldService.Processor<HelloWorldService.Iface>(
29             // new HelloWorldImpl());
30  
31             // 简单的单线程服务模型,一般用于测试
32             TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
33             TServer.Args tArgs = new TServer.Args(serverTransport);
34             tArgs.processor(tprocessor);
35             tArgs.protocolFactory(new TBinaryProtocol.Factory());
36             // tArgs.protocolFactory(new TCompactProtocol.Factory());
37             // tArgs.protocolFactory(new TJSONProtocol.Factory());
38             TServer server = new TSimpleServer(tArgs);
39             server.serve();
40  
41         } catch (Exception e) {
42             System.out.println("Server start error!!!");
43             e.printStackTrace();
44         }
45     }
46  
47     /**
48      * @param args
49      */
50     public static void main(String[] args) {
51         HelloServerDemo server = new HelloServerDemo();
52         server.startServer();
53     }
54  
55 }

编写客户端Client代码:HelloClientDemo.java

1 package com.micmiu.thrift.demo;
2  
3 import org.apache.thrift.TException;
4 import org.apache.thrift.protocol.TBinaryProtocol;
5 import org.apache.thrift.protocol.TCompactProtocol;
6 import org.apache.thrift.protocol.TJSONProtocol;
7 import org.apache.thrift.protocol.TProtocol;
8 import org.apache.thrift.transport.TSocket;
9 import org.apache.thrift.transport.TTransport;
10 import org.apache.thrift.transport.TTransportException;
11  
12 /**
13  * blog http://www.micmiu.com
14  *
15  * @author Michael
16  *
17  */
18 public class HelloClientDemo {
19  
20     public static final String SERVER_IP = "localhost";
21     public static final int SERVER_PORT = 8090;
22     public static final int TIMEOUT = 30000;
23  
24     /**
25      *
26      * @param userName
27      */
28     public void startClient(String userName) {
29         TTransport transport = null;
30         try {
31             transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
32             // 协议要和服务端一致
33             TProtocol protocol = new TBinaryProtocol(transport);
34             // TProtocol protocol = new TCompactProtocol(transport);
35             // TProtocol protocol = new TJSONProtocol(transport);
36             HelloWorldService.Client client = new HelloWorldService.Client(
37                     protocol);
38             transport.open();
39             String result = client.sayHello(userName);
40             System.out.println("Thrify client result =: " + result);
41         } catch (TTransportException e) {
42             e.printStackTrace();
43         } catch (TException e) {
44             e.printStackTrace();
45         } finally {
46             if (null != transport) {
47                 transport.close();
48             }
49         }
50     }
51  
52     /**
53      * @param args
54      */
55     public static void main(String[] args) {
56         HelloClientDemo client = new HelloClientDemo();
57         client.startClient("Michael");
58  
59     }
60  
61 }

先运行服务端程序,日志如下:

HelloWorld TSimpleServer start ....

再运行客户端调用程序,日志如下:

Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com

测试成功,和预期的返回信息一致。

4.TThreadPoolServer 服务模型

线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。

编写服务端代码:HelloServerDemo.java

1 package com.micmiu.thrift.demo;
2  
3 import org.apache.thrift.TProcessor;
4 import org.apache.thrift.protocol.TBinaryProtocol;
5 import org.apache.thrift.server.TServer;
6 import org.apache.thrift.server.TThreadPoolServer;
7 import org.apache.thrift.transport.TServerSocket;
8  
9 /**
10  * blog http://www.micmiu.com
11  *
12  * @author Michael
13  *
14  */
15 public class HelloServerDemo {
16     public static final int SERVER_PORT = 8090;
17  
18     public void startServer() {
19         try {
20             System.out.println("HelloWorld TThreadPoolServer start ....");
21  
22             TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
23                     new HelloWorldImpl());
24  
25              TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
26              TThreadPoolServer.Args ttpsArgs = new TThreadPoolServer.Args(
27              serverTransport);
28              ttpsArgs.processor(tprocessor);
29              ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());
30  
31             // 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
32              TServer server = new TThreadPoolServer(ttpsArgs);
33              server.serve();
34  
35         } catch (Exception e) {
36             System.out.println("Server start error!!!");
37             e.printStackTrace();
38         }
39     }
40  
41     /**
42      * @param args
43      */
44     public static void main(String[] args) {
45         HelloServerDemo server = new HelloServerDemo();
46         server.startServer();
47     }
48  
49 }

客户端Client代码和之前的一样,只要数据传输的协议一致即可,客户端测试成功,结果如下:

Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com

5.TNonblockingServer 服务模型

使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式。

编写服务端代码:HelloServerDemo.java

1 package com.micmiu.thrift.demo;
2  
3 import org.apache.thrift.TProcessor;
4

抱歉!评论已关闭.