您的位置:首页 > 编程语言 > Java开发

Thrift入门及Java实例演示

2014-04-04 10:53 375 查看
最近遇到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.

————

转载自micmiu – 软件开发+生活点滴[ http://www.micmiu.com/ ]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: