Thrift入门及Java实例演示


Thrift入门及Java实例演示

作者: Michael 日期: 2012 6 14 日发表评论 (29)查看评论

目录:

       概述

       下载配置

       基本概念

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年四月开放源码,085月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

官网地址:thrift.apache.org

推荐值得一看的文章:

       http://jnb.ociweb.com/jnb/jnbJun2009.html

       http://wiki.apache.org/thrift

       http://thrift.apache.org/static/files/thrift-20070401.pdf

[]、下载配置

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

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

XHTML

 <dependency>

 <groupId>org.apache.thrift</groupId>

 <artifactId>libthrift</artifactId>

 <version>0.8.0</version>

</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.数据类型

       基本类型:

o       bool:布尔值,true false,对应 Java boolean

o       byte8 位有符号整数,对应Java byte

o       i1616 位有符号整数,对应Java short

o       i3232 位有符号整数,对应Java int

o       i6464 位有符号整数,对应Java long

o       double64 位浮点数,对应 Java double

o       stringutf-8编码的字符串,对应Java String

       结构体类型:

o       struct:定义公共的对象,类似于C 语言中的结构体定义,在 Java 中是一个 JavaBean

       容器类型:

o       list:对应 Java ArrayList

o       set:对应 Java HashSet

o       map:对应 Java HashMap

       异常类型:

o       exception:对应 Java Exception

       服务类型:

o       service:对应服务的类

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

       实现服务处理接口impl

       创建TProcessor

       创建TServerTransport

       创建TProtocol

       创建TServer

       启动Server

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

       创建Transport

       创建TProtocol

       基于TTransportTProtocol创建 Client

       调用Client的相应方法

4.数据传输协议

       TBinaryProtocol : 二进制格式.

       TCompactProtocol : 压缩格式

       TJSONProtocol : JSON格式

       TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

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

[]、实例演示

1. thrift生成代码

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

 

namespace java com.micmiu.thrift.demo

 

service HelloWorldService {

  stringsayHello(1:string username)

}

目录结构如下:

 G:\test\thrift&gt;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&gt;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中增加如下内容:

XHTML

 <dependency>

         <groupId>org.apache.thrift</groupId>

         <artifactId>libthrift</artifactId>

         <version>0.8.0</version>

</dependency>

<dependency>

         <groupId>org.slf4j</groupId>

         <artifactId>slf4j-log4j12</artifactId>

         <version>1.5.8</version>

</dependency>

2. 实现接口Iface

java代码:HelloWorldImpl.java

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TException;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloWorldImpl implementsHelloWorldService.Iface {

 

         publicHelloWorldImpl() {

         }

 

         @Override

         publicString sayHello(String username) throws TException {

                   return"Hi," + username + " welcome to my blog www.micmiu.com";

         }

 

}

3.TSimpleServer服务端

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

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

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TProcessor;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.protocol.TCompactProtocol;

import org.apache.thrift.protocol.TJSONProtocol;

importorg.apache.thrift.protocol.TSimpleJSONProtocol;

import org.apache.thrift.server.TServer;

import org.apache.thrift.server.TSimpleServer;

import org.apache.thrift.transport.TServerSocket;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloServerDemo {

         publicstatic final int SERVER_PORT = 8090;

 

         publicvoid startServer() {

                   try{

                            System.out.println("HelloWorldTSimpleServer start ....");

 

                            TProcessortprocessor = new HelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(

                                               newHelloWorldImpl());

                            //HelloWorldService.Processor&lt;HelloWorldService.Iface&gt; tprocessor =

                            //new HelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(

                            //new HelloWorldImpl());

 

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

                            TServerSocketserverTransport = new TServerSocket(SERVER_PORT);

                            TServer.ArgstArgs = new TServer.Args(serverTransport);

                            tArgs.processor(tprocessor);

                            tArgs.protocolFactory(newTBinaryProtocol.Factory());

                            //tArgs.protocolFactory(new TCompactProtocol.Factory());

                            //tArgs.protocolFactory(new TJSONProtocol.Factory());

                            TServerserver = new TSimpleServer(tArgs);

                            server.serve();

 

                   }catch (Exception e) {

                            System.out.println("Serverstart error!!!");

                            e.printStackTrace();

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloServerDemoserver = new HelloServerDemo();

                   server.startServer();

         }

 

}

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

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TException;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.protocol.TCompactProtocol;

import org.apache.thrift.protocol.TJSONProtocol;

import org.apache.thrift.protocol.TProtocol;

import org.apache.thrift.transport.TSocket;

import org.apache.thrift.transport.TTransport;

import org.apache.thrift.transport.TTransportException;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloClientDemo {

 

         publicstatic final String SERVER_IP = "localhost";

         publicstatic final int SERVER_PORT = 8090;

         publicstatic final int TIMEOUT = 30000;

 

         /**

          *

          * @param userName

          */

         publicvoid startClient(String userName) {

                   TTransporttransport = null;

                   try{

                            transport= new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);

                            //协议要和服务端一致

                            TProtocolprotocol = new TBinaryProtocol(transport);

                            //TProtocol protocol = new TCompactProtocol(transport);

                            //TProtocol protocol = new TJSONProtocol(transport);

                            HelloWorldService.Clientclient = new HelloWorldService.Client(

                                               protocol);

                            transport.open();

                            Stringresult = client.sayHello(userName);

                            System.out.println("Thrifyclient result =: " + result);

                   }catch (TTransportException e) {

                            e.printStackTrace();

                   }catch (TException e) {

                            e.printStackTrace();

                   }finally {

                            if(null != transport) {

                                     transport.close();

                            }

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloClientDemoclient = new HelloClientDemo();

                   client.startClient("Michael");

 

         }

 

}

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

 

1       HelloWorldTSimpleServer start ....

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

 

1       Thrifyclient result =: Hi,Michael welcome to my blog www.micmiu.com

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

4.TThreadPoolServer 服务模型

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

编写服务端代码:HelloServerDemo.java

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TProcessor;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.server.TServer;

import org.apache.thrift.server.TThreadPoolServer;

import org.apache.thrift.transport.TServerSocket;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloServerDemo {

         publicstatic final int SERVER_PORT = 8090;

 

         publicvoid startServer() {

                   try{

                            System.out.println("HelloWorldTThreadPoolServer start ....");

 

                            TProcessortprocessor = newHelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(

                                               newHelloWorldImpl());

 

                             TServerSocket serverTransport = newTServerSocket(SERVER_PORT);

                             TThreadPoolServer.Args ttpsArgs = newTThreadPoolServer.Args(

                             serverTransport);

                             ttpsArgs.processor(tprocessor);

                             ttpsArgs.protocolFactory(newTBinaryProtocol.Factory());

 

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

                             TServer server = newTThreadPoolServer(ttpsArgs);

                             server.serve();

 

                   }catch (Exception e) {

                            System.out.println("Serverstart error!!!");

                            e.printStackTrace();

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloServerDemoserver = new HelloServerDemo();

                   server.startServer();

         }

 

}

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

 

1       Thrifyclient result =: Hi,Michael welcome to my blog www.micmiu.com

5.TNonblockingServer 服务模型

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

编写服务端代码:HelloServerDemo.java

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TProcessor;

import org.apache.thrift.protocol.TCompactProtocol;

import org.apache.thrift.server.TNonblockingServer;

import org.apache.thrift.server.TServer;

importorg.apache.thrift.transport.TFramedTransport;

importorg.apache.thrift.transport.TNonblockingServerSocket;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloServerDemo {

         publicstatic final int SERVER_PORT = 8090;

 

         publicvoid startServer() {

                   try{

                            System.out.println("HelloWorldTNonblockingServer start ....");

 

                            TProcessortprocessor = newHelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(

                                               newHelloWorldImpl());

 

                            TNonblockingServerSockettnbSocketTransport = new TNonblockingServerSocket(

                                               SERVER_PORT);

                            TNonblockingServer.ArgstnbArgs = new TNonblockingServer.Args(

                                               tnbSocketTransport);

                            tnbArgs.processor(tprocessor);

                            tnbArgs.transportFactory(newTFramedTransport.Factory());

                            tnbArgs.protocolFactory(newTCompactProtocol.Factory());

 

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

                            TServerserver = new TNonblockingServer(tnbArgs);

                            server.serve();

 

                   }catch (Exception e) {

                            System.out.println("Serverstart error!!!");

                            e.printStackTrace();

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloServerDemoserver = new HelloServerDemo();

                   server.startServer();

         }

 

}

编写客户端代码:HelloClientDemo.java

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TException;

import org.apache.thrift.protocol.TCompactProtocol;

import org.apache.thrift.protocol.TProtocol;

importorg.apache.thrift.transport.TFramedTransport;

import org.apache.thrift.transport.TSocket;

import org.apache.thrift.transport.TTransport;

importorg.apache.thrift.transport.TTransportException;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloClientDemo {

 

         publicstatic final String SERVER_IP = "localhost";

         publicstatic final int SERVER_PORT = 8090;

         publicstatic final int TIMEOUT = 30000;

 

         /**

          *

          * @param userName

          */

         publicvoid startClient(String userName) {

                   TTransporttransport = null;

                   try{

                            transport= new TFramedTransport(new TSocket(SERVER_IP,

                                               SERVER_PORT,TIMEOUT));

                            //协议要和服务端一致

                            TProtocolprotocol = new TCompactProtocol(transport);

                            HelloWorldService.Clientclient = new HelloWorldService.Client(

                                               protocol);

                            transport.open();

                            Stringresult = client.sayHello(userName);

                            System.out.println("Thrifyclient result =: " + result);

                   }catch (TTransportException e) {

                            e.printStackTrace();

                   }catch (TException e) {

                            e.printStackTrace();

                   }finally {

                            if(null != transport) {

                                     transport.close();

                            }

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloClientDemoclient = new HelloClientDemo();

                   client.startClient("Michael");

 

         }

 

}

客户端的测试成功,结果如下:

 

1       Thrifyclient result =: Hi,Michael welcome to my blog www.micmiu.com

6.THsHaServer服务模型

半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式。

编写服务端代码:HelloServerDemo.java

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TProcessor;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.protocol.TCompactProtocol;

import org.apache.thrift.server.THsHaServer;

import org.apache.thrift.server.TNonblockingServer;

import org.apache.thrift.server.TServer;

import org.apache.thrift.server.TSimpleServer;

import org.apache.thrift.server.TThreadPoolServer;

importorg.apache.thrift.transport.TFramedTransport;

import org.apache.thrift.transport.TNonblockingServerSocket;

import org.apache.thrift.transport.TServerSocket;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloServerDemo {

         publicstatic final int SERVER_PORT = 8090;

 

         publicvoid startServer() {

                   try{

                            System.out.println("HelloWorldTHsHaServer start ....");

 

                            TProcessortprocessor = newHelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(

                                               newHelloWorldImpl());

 

                            TNonblockingServerSockettnbSocketTransport = new TNonblockingServerSocket(

                                               SERVER_PORT);

                            THsHaServer.ArgsthhsArgs = new THsHaServer.Args(tnbSocketTransport);

                            thhsArgs.processor(tprocessor);

                            thhsArgs.transportFactory(newTFramedTransport.Factory());

                            thhsArgs.protocolFactory(newTBinaryProtocol.Factory());

 

                            //半同步半异步的服务模型

                            TServerserver = new THsHaServer(thhsArgs);

                            server.serve();

 

                   }catch (Exception e) {

                            System.out.println("Serverstart error!!!");

                            e.printStackTrace();

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloServerDemoserver = new HelloServerDemo();

                   server.startServer();

         }

 

}

客户端代码和上面 4 中的类似,只要注意传输协议一致以及指定传输方式为TFramedTransport

7.异步客户端

编写服务端代码:HelloServerDemo.java

 packagecom.micmiu.thrift.demo;

 

import org.apache.thrift.TProcessor;

import org.apache.thrift.protocol.TCompactProtocol;

import org.apache.thrift.server.TNonblockingServer;

import org.apache.thrift.server.TServer;

importorg.apache.thrift.transport.TFramedTransport;

importorg.apache.thrift.transport.TNonblockingServerSocket;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloServerDemo {

         publicstatic final int SERVER_PORT = 8090;

 

         publicvoid startServer() {

                   try{

                            System.out.println("HelloWorldTNonblockingServer start ....");

 

                            TProcessortprocessor = newHelloWorldService.Processor&lt;HelloWorldService.Iface&gt;(

                                               newHelloWorldImpl());

 

                            TNonblockingServerSockettnbSocketTransport = new TNonblockingServerSocket(

                                               SERVER_PORT);

                            TNonblockingServer.ArgstnbArgs = new TNonblockingServer.Args(

                                               tnbSocketTransport);

                            tnbArgs.processor(tprocessor);

                            tnbArgs.transportFactory(newTFramedTransport.Factory());

                            tnbArgs.protocolFactory(newTCompactProtocol.Factory());

 

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

                            TServerserver = new TNonblockingServer(tnbArgs);

                            server.serve();

 

                   }catch (Exception e) {

                            System.out.println("Serverstart error!!!");

                            e.printStackTrace();

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloServerDemoserver = new HelloServerDemo();

                   server.startServer();

         }

 

}

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

 packagecom.micmiu.thrift.demo;

 

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.TimeUnit;

 

import org.apache.thrift.TException;

import org.apache.thrift.async.AsyncMethodCallback;

import org.apache.thrift.async.TAsyncClientManager;

import org.apache.thrift.protocol.TCompactProtocol;

import org.apache.thrift.protocol.TProtocolFactory;

importorg.apache.thrift.transport.TNonblockingSocket;

importorg.apache.thrift.transport.TNonblockingTransport;

 

importcom.micmiu.thrift.demo.HelloWorldService.AsyncClient.sayHello_call;

 

/**

 * bloghttp://www.micmiu.com

 *

 * @authorMichael

 *

 */

public class HelloAsynClientDemo {

 

         publicstatic final String SERVER_IP = "localhost";

         publicstatic final int SERVER_PORT = 8090;

         publicstatic final int TIMEOUT = 30000;

 

         /**

          *

          * @param userName

          */

         publicvoid startClient(String userName) {

                   try{

                            TAsyncClientManagerclientManager = new TAsyncClientManager();

                            TNonblockingTransporttransport = new TNonblockingSocket(SERVER_IP,

                                               SERVER_PORT,TIMEOUT);

 

                            TProtocolFactorytprotocol = new TCompactProtocol.Factory();

                            HelloWorldService.AsyncClientasyncClient = new HelloWorldService.AsyncClient(

                                               tprotocol,clientManager, transport);

                            System.out.println("Clientstart .....");

 

                            CountDownLatchlatch = new CountDownLatch(1);

                            AsynCallbackcallBack = new AsynCallback(latch);

                            System.out.println("callmethod sayHello start ...");

                            asyncClient.sayHello(userName,callBack);

                            System.out.println("callmethod sayHello .... end");

                            booleanwait = latch.await(30, TimeUnit.SECONDS);

                            System.out.println("latch.await=:" + wait);

                   }catch (Exception e) {

                            e.printStackTrace();

                   }

                   System.out.println("startClientend.");

         }

 

         publicclass AsynCallback implements AsyncMethodCallback&lt;sayHello_call&gt;{

                   privateCountDownLatch latch;

 

                   publicAsynCallback(CountDownLatch latch) {

                            this.latch= latch;

                   }

 

                   @Override

                   publicvoid onComplete(sayHello_call response) {

                            System.out.println("onComplete");

                            try{

                                     //Thread.sleep(1000L * 1);

                                     System.out.println("AsynCallresult =:"

                                                        +response.getResult().toString());

                            }catch (TException e) {

                                     e.printStackTrace();

                            }catch (Exception e) {

                                     e.printStackTrace();

                            }finally {

                                     latch.countDown();

                            }

                   }

 

                   @Override

                   publicvoid onError(Exception exception) {

                            System.out.println("onError:" + exception.getMessage());

                            latch.countDown();

                   }

         }

 

         /**

          * @param args

          */

         publicstatic void main(String[] args) {

                   HelloAsynClientDemoclient = new HelloAsynClientDemo();

                   client.startClient("Michael");

 

         }

 

}

先运行服务程序,再运行客户端程序,测试结果如下:

 Client start.....

call method sayHello start ...

call method sayHello .... end

onComplete

AsynCall result =:Hi,Michael welcome to my blogwww.micmiu.com

latch.await =:true

startClient end.

――――

原创文章,转载请注明:转载自micmiu �C软件开发+生活点滴[ http://www.micmiu.com/ ]

本文链接地址: http://www.micmiu.com/soa/rpc/thrift-sample/

你可能感兴趣的:(java,michael)