Thrift入门及Java实例演示

最近遇到Thrift相关的问题,查阅了网上的资料。很快解决了问题,感谢大神的文章。记录下来,以备以后查阅。

目录:

概述
下载配置
基本概念
数据类型
服务端编码基本步骤
客户端编码基本步骤
数据传输协议
实例演示(java)
 thrift生成代码
 实现接口Iface
TSimpleServer服务模型
TThreadPoolServer 服务模型
TNonblockingServer 服务模型
THsHaServer服务模型
异步客户端
[一]、概述
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
[二]、下载配置
到官网下载最新版本,目前最新版本为0.9.1.
1. 如果是Maven构建项目的,直接在pom.xml 中添加如下内容:
1    <dependency>

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

3      <artifactId>libthrift</artifactId>

4      <version>0.9.1</version>

5    </dependency>
2.如果自己编译lib包,把下载的压缩包解压到X:盘,然后在X:\thrift-0.9.1\lib\java 目录下运行ant进行自动编译,会在X:\thrift-0.9.1\lib\java\build\ 目录下看到编译好的lib包:libthrift-0.9.1.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.zhaosoft.thrift.demo

3    service  HelloWorldService {

4      string sayHello(1:string username)

5    }
目录结构如下:
G:\test\thrift>tree /F
G:.
    demoHello.thrift
    demouser.thrift
    thrift-0.9.1.exe

没有子文件夹
thrift-0.9.1.exe 是官网提供的windows下编译工具,运用这个工具生成相关代码:
1    thrift-0.9.1.exe -r -gen java ./demoHello.thrift
生成后的目录结构如下:
G:\test\thrift>tree /F
G:.
│  demoHello.thrift
│  demouser.thrift
│  thrift-0.9.1.exe

└─gen-java
    └─com
        └─zhaosoft
            └─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.9.1</version>

5    </dependency>

6    <dependency>

7        <groupId>org.slf4j</groupId>

8        <artifactId>slf4j-log4j12</artifactId>

9        <version>1.7.6</version>

10    </dependency>
2.      实现接口Iface
        java代码:HelloWorldImpl.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TException;

4    

5    /**

6     *


7     *

8     *


9     *

10     */

11    publicclassHelloWorldImplimplementsHelloWorldService.Iface {

12    

13        publicHelloWorldImpl() {

14        }

15    

16        @Override

17        publicString sayHello(String username)throwsTException {

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

19        }

20    

21    }
3.TSimpleServer服务端
简单的单线程服务模型,一般用于测试。
编写服务端server代码:HelloServerDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TProcessor;

4    importorg.apache.thrift.protocol.TBinaryProtocol;

5    importorg.apache.thrift.protocol.TCompactProtocol;

6    importorg.apache.thrift.protocol.TJSONProtocol;

7    importorg.apache.thrift.protocol.TSimpleJSONProtocol;

8    importorg.apache.thrift.server.TServer;

9    importorg.apache.thrift.server.TSimpleServer;

10    importorg.apache.thrift.transport.TServerSocket;

11    

12    /**

13     *


14     *

15     *


16     *

17     */

18    publicclassHelloServerDemo {

19        publicstaticfinalintSERVER_PORT =80;

20    

21        publicvoidstartServer() {

22            try{

23                System.out.println("HelloWorld TSimpleServer start ....");

24    

25                TProcessor tprocessor =newHelloWorldService.Processor<HelloWorldService.Iface>(

26                        newHelloWorldImpl());

27                // HelloWorldService.Processor<HelloWorldService.Iface> tprocessor =

28                // new HelloWorldService.Processor<HelloWorldService.Iface>(

29                // new HelloWorldImpl());

30    

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

32                TServerSocket serverTransport =newTServerSocket(SERVER_PORT);

33                TServer.Args tArgs =newTServer.Args(serverTransport);

34                tArgs.processor(tprocessor);

35                tArgs.protocolFactory(newTBinaryProtocol.Factory());

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

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

38                TServer server =newTSimpleServer(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        publicstaticvoidmain(String[] args) {

51            HelloServerDemo server =newHelloServerDemo();

52            server.startServer();

53        }

54    

55    }
编写客户端Client代码:HelloClientDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TException;

4    importorg.apache.thrift.protocol.TBinaryProtocol;

5    importorg.apache.thrift.protocol.TCompactProtocol;

6    importorg.apache.thrift.protocol.TJSONProtocol;

7    importorg.apache.thrift.protocol.TProtocol;

8    importorg.apache.thrift.transport.TSocket;

9    importorg.apache.thrift.transport.TTransport;

10    importorg.apache.thrift.transport.TTransportException;

11    

12    /**

13     * blog http://www.zhaosoft.com

14     *

15     * @author zxl

16     *

17     */

18    publicclassHelloClientDemo {

19    

20        publicstaticfinalString SERVER_IP ="localhost";

21        publicstaticfinalintSERVER_PORT =80;

22        publicstaticfinalintTIMEOUT =30000;

23    

24        /**

25         *

26         * @param userName

27         */

28        publicvoidstartClient(String userName) {

29            TTransport transport =null;

30            try{

31                transport =newTSocket(SERVER_IP, SERVER_PORT, TIMEOUT);

32                // 协议要和服务端一致

33                TProtocol protocol =newTBinaryProtocol(transport);

34                // TProtocol protocol = new TCompactProtocol(transport);

35                // TProtocol protocol = new TJSONProtocol(transport);

36                HelloWorldService.Client client =newHelloWorldService.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        publicstaticvoidmain(String[] args) {

56            HelloClientDemo client =newHelloClientDemo();

57            client.startClient("zxl");

58    

59        }

60    

61    }
先运行服务端程序,日志如下:
HelloWorld TSimpleServer start ....
再运行客户端调用程序,日志如下:
Thrify client result =: Hi,zxl welcome to my blog www.zhaosoft.com
测试成功,和预期的返回信息一致。
4.TThreadPoolServer 服务模型
线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
编写服务端代码:HelloServerDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TProcessor;

4    importorg.apache.thrift.protocol.TBinaryProtocol;

5    importorg.apache.thrift.server.TServer;

6    importorg.apache.thrift.server.TThreadPoolServer;

7    importorg.apache.thrift.transport.TServerSocket;

8    

9    /**

10     * blog http://www.zhaosoft.com

11     *

12     * @author zxl

13     *

14     */

15    publicclassHelloServerDemo {

16        publicstaticfinalintSERVER_PORT =80;

17    

18        publicvoidstartServer() {

19            try{

20                System.out.println("HelloWorld TThreadPoolServer start ....");

21    

22                TProcessor tprocessor =newHelloWorldService.Processor<HelloWorldService.Iface>(

23                        newHelloWorldImpl());

24    

25                 TServerSocket serverTransport =newTServerSocket(SERVER_PORT);

26                 TThreadPoolServer.Args ttpsArgs =newTThreadPoolServer.Args(

27                 serverTransport);

28                 ttpsArgs.processor(tprocessor);

29                 ttpsArgs.protocolFactory(newTBinaryProtocol.Factory());

30    

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

32                 TServer server =newTThreadPoolServer(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        publicstaticvoidmain(String[] args) {

45            HelloServerDemo server =newHelloServerDemo();

46            server.startServer();

47        }

48    

49    }
客户端Client代码和之前的一样,只要数据传输的协议一致即可,客户端测试成功,结果如下:
Thrify client result =: Hi,zxl welcome to my blog www.zhaosoft.com
5.TNonblockingServer 服务模型
使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式。
编写服务端代码:HelloServerDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TProcessor;

4    importorg.apache.thrift.protocol.TCompactProtocol;

5    importorg.apache.thrift.server.TNonblockingServer;

6    importorg.apache.thrift.server.TServer;

7    importorg.apache.thrift.transport.TFramedTransport;

8    importorg.apache.thrift.transport.TNonblockingServerSocket;

9    

10    /**

11     * blog http://www.zhaosoft.com

12     *

13     * @author zxl

14     *

15     */

16    publicclassHelloServerDemo {

17        publicstaticfinalintSERVER_PORT =80;

18    

19        publicvoidstartServer() {

20            try{

21                System.out.println("HelloWorld TNonblockingServer start ....");

22    

23                TProcessor tprocessor =newHelloWorldService.Processor<HelloWorldService.Iface>(

24                        newHelloWorldImpl());

25    

26                TNonblockingServerSocket tnbSocketTransport =newTNonblockingServerSocket(

27                        SERVER_PORT);

28                TNonblockingServer.Args tnbArgs =newTNonblockingServer.Args(

29                        tnbSocketTransport);

30                tnbArgs.processor(tprocessor);

31                tnbArgs.transportFactory(newTFramedTransport.Factory());

32                tnbArgs.protocolFactory(newTCompactProtocol.Factory());

33    

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

35                TServer server =newTNonblockingServer(tnbArgs);

36                server.serve();

37    

38            }catch(Exception e) {

39                System.out.println("Server start error!!!");

40                e.printStackTrace();

41            }

42        }

43    

44        /**

45         * @param args

46         */

47        publicstaticvoidmain(String[] args) {

48            HelloServerDemo server =newHelloServerDemo();

49            server.startServer();

50        }

51    

52    }
编写客户端代码:HelloClientDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TException;

4    importorg.apache.thrift.protocol.TCompactProtocol;

5    importorg.apache.thrift.protocol.TProtocol;

6    importorg.apache.thrift.transport.TFramedTransport;

7    importorg.apache.thrift.transport.TSocket;

8    importorg.apache.thrift.transport.TTransport;

9    importorg.apache.thrift.transport.TTransportException;

10    

11    /**

12     * blog http://www.zhaosoft.com

13     *

14     * @author zxl

15     *

16     */

17    publicclassHelloClientDemo {

18    

19        publicstaticfinalString SERVER_IP ="localhost";

20        publicstaticfinalintSERVER_PORT =80;

21        publicstaticfinalintTIMEOUT =30000;

22    

23        /**

24         *

25         * @param userName

26         */

27        publicvoidstartClient(String userName) {

28            TTransport transport =null;

29            try{

30                transport =newTFramedTransport(newTSocket(SERVER_IP,

31                        SERVER_PORT, TIMEOUT));

32                // 协议要和服务端一致

33                TProtocol protocol =newTCompactProtocol(transport);

34                HelloWorldService.Client client =newHelloWorldService.Client(

35                        protocol);

36                transport.open();

37                String result = client.sayHello(userName);

38                System.out.println("Thrify client result =: "+ result);

39            }catch(TTransportException e) {

40                e.printStackTrace();

41            }catch(TException e) {

42                e.printStackTrace();

43            }finally{

44                if(null!= transport) {

45                    transport.close();

46                }

47            }

48        }

49    

50        /**

51         * @param args

52         */

53        publicstaticvoidmain(String[] args) {

54            HelloClientDemo client =newHelloClientDemo();

55            client.startClient("zxl");

56    

57        }

58    

59    }
客户端的测试成功,结果如下:
Thrify client result =: Hi,zxl welcome to my blog www.zhaosoft.com
6.THsHaServer服务模型
半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式。
编写服务端代码:HelloServerDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TProcessor;

4    importorg.apache.thrift.protocol.TBinaryProtocol;

5    importorg.apache.thrift.protocol.TCompactProtocol;

6    importorg.apache.thrift.server.THsHaServer;

7    importorg.apache.thrift.server.TNonblockingServer;

8    importorg.apache.thrift.server.TServer;

9    importorg.apache.thrift.server.TSimpleServer;

10    importorg.apache.thrift.server.TThreadPoolServer;

11    importorg.apache.thrift.transport.TFramedTransport;

12    importorg.apache.thrift.transport.TNonblockingServerSocket;

13    importorg.apache.thrift.transport.TServerSocket;

14    

15    /**

16     * blog http://www.zhaosoft.com

17     *

18     * @author zxl

19     *

20     */

21    publicclassHelloServerDemo {

22        publicstaticfinalintSERVER_PORT =80;

23    

24        publicvoidstartServer() {

25            try{

26                System.out.println("HelloWorld THsHaServer start ....");

27    

28                TProcessor tprocessor =newHelloWorldService.Processor<HelloWorldService.Iface>(

29                        newHelloWorldImpl());

30    

31                TNonblockingServerSocket tnbSocketTransport =newTNonblockingServerSocket(

32                        SERVER_PORT);

33                THsHaServer.Args thhsArgs =newTHsHaServer.Args(tnbSocketTransport);

34                thhsArgs.processor(tprocessor);

35                thhsArgs.transportFactory(newTFramedTransport.Factory());

36                thhsArgs.protocolFactory(newTBinaryProtocol.Factory());

37    

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

39                TServer server =newTHsHaServer(thhsArgs);

40                server.serve();

41    

42            }catch(Exception e) {

43                System.out.println("Server start error!!!");

44                e.printStackTrace();

45            }

46        }

47    

48        /**

49         * @param args

50         */

51        publicstaticvoidmain(String[] args) {

52            HelloServerDemo server =newHelloServerDemo();

53            server.startServer();

54        }

55    

56    }
客户端代码和上面 4 中的类似,只要注意传输协议一致以及指定传输方式为TFramedTransport。
7.异步客户端
编写服务端代码:HelloServerDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importorg.apache.thrift.TProcessor;

4    importorg.apache.thrift.protocol.TCompactProtocol;

5    importorg.apache.thrift.server.TNonblockingServer;

6    importorg.apache.thrift.server.TServer;

7    importorg.apache.thrift.transport.TFramedTransport;

8    importorg.apache.thrift.transport.TNonblockingServerSocket;

9    

10    /**

11     * blog http://www.zhaosoft.com

12     *

13     * @author zxl

14     *

15     */

16    publicclassHelloServerDemo {

17        publicstaticfinalintSERVER_PORT =80;

18    

19        publicvoidstartServer() {

20            try{

21                System.out.println("HelloWorld TNonblockingServer start ....");

22    

23                TProcessor tprocessor =newHelloWorldService.Processor<HelloWorldService.Iface>(

24                        newHelloWorldImpl());

25    

26                TNonblockingServerSocket tnbSocketTransport =newTNonblockingServerSocket(

27                        SERVER_PORT);

28                TNonblockingServer.Args tnbArgs =newTNonblockingServer.Args(

29                        tnbSocketTransport);

30                tnbArgs.processor(tprocessor);

31                tnbArgs.transportFactory(newTFramedTransport.Factory());

32                tnbArgs.protocolFactory(newTCompactProtocol.Factory());

33    

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

35                TServer server =newTNonblockingServer(tnbArgs);

36                server.serve();

37    

38            }catch(Exception e) {

39                System.out.println("Server start error!!!");

40                e.printStackTrace();

41            }

42        }

43    

44        /**

45         * @param args

46         */

47        publicstaticvoidmain(String[] args) {

48            HelloServerDemo server =newHelloServerDemo();

49            server.startServer();

50        }

51    

52    }
编写客户端Client代码:HelloAsynClientDemo.java
1    packagecom.zhaosoft.thrift.demo;

2    

3    importjava.util.concurrent.CountDownLatch;

4    importjava.util.concurrent.TimeUnit;

5    

6    importorg.apache.thrift.TException;

7    importorg.apache.thrift.async.AsyncMethodCallback;

8    importorg.apache.thrift.async.TAsyncClientManager;

9    importorg.apache.thrift.protocol.TCompactProtocol;

10    importorg.apache.thrift.protocol.TProtocolFactory;

11    importorg.apache.thrift.transport.TNonblockingSocket;

12    importorg.apache.thrift.transport.TNonblockingTransport;

13    

14    importcom.zhaosoft.thrift.demo.HelloWorldService.AsyncClient.sayHello_call;

15    

16    /**

17     * blog http://www.zhaosoft.com

18     *

19     * @author zxl

20     *

21     */

22    publicclassHelloAsynClientDemo {

23    

24        publicstaticfinalString SERVER_IP ="localhost";

25        publicstaticfinalintSERVER_PORT =80;

26        publicstaticfinalintTIMEOUT =30000;

27    

28        /**

29         *

30         * @param userName

31         */

32        publicvoidstartClient(String userName) {

33            try{

34                TAsyncClientManager clientManager =newTAsyncClientManager();

35                TNonblockingTransport transport =newTNonblockingSocket(SERVER_IP,

36                        SERVER_PORT, TIMEOUT);

37    

38                TProtocolFactory tprotocol =newTCompactProtocol.Factory();

39                HelloWorldService.AsyncClient asyncClient =newHelloWorldService.AsyncClient(

40                        tprotocol, clientManager, transport);

41                System.out.println("Client start .....");

42    

43                CountDownLatch latch =newCountDownLatch(1);

44                AsynCallback callBack =newAsynCallback(latch);

45                System.out.println("call method sayHello start ...");

46                asyncClient.sayHello(userName, callBack);

47                System.out.println("call method sayHello .... end");

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

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

50            }catch(Exception e) {

51                e.printStackTrace();

52            }

53            System.out.println("startClient end.");

54        }

55    

56        publicclassAsynCallbackimplementsAsyncMethodCallback<sayHello_call> {

57            privateCountDownLatch latch;

58    

59            publicAsynCallback(CountDownLatch latch) {

60                this.latch = latch;

61            }

62    

63            @Override

64            publicvoidonComplete(sayHello_call response) {

65                System.out.println("onComplete");

66                try{

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

68                    System.out.println("AsynCall result =:"

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

70                }catch(TException e) {

71                    e.printStackTrace();

72                }catch(Exception e) {

73                    e.printStackTrace();

74                }finally{

75                    latch.countDown();

76                }

77            }

78    

79            @Override

80            publicvoidonError(Exception exception) {

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

82                latch.countDown();

83            }

84        }

85    

86        /**

87         * @param args

88         */

89        publicstaticvoidmain(String[] args) {

90            HelloAsynClientDemo client =newHelloAsynClientDemo();

91            client.startClient("zxl");

92    

93        }

94    

95    }
先运行服务程序,再运行客户端程序,测试结果如下:
Client start .....
call method sayHello start ...
call method sayHello .... end
onComplete
AsynCall result =:Hi,zxl welcome to my blog www.zhaosoft.com
latch.await =:true
startClient end.
————


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值