目录:
[一]、概述
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 中添加如下内容:
monospace !important; direction: ltr !important; display: block !important;">1
class="plain" style="margin: 0px !important; padding: 0px !important; border: 0px !important; vertical-align: baseline !important; background-image: none !important; float: none !important; height: auto !important; width: auto !important; line-height: 1.1em !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; direction: ltr !important; display: inline !important;"><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.数据类型
2.服务端编码基本步骤:
3.客户端编码基本步骤:
4.数据传输协议
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
/**
6
?* blog?http://www.micmiu.com
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 =?newHelloWorldService.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 =?newTServerSocket(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 =?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
????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 =?newHelloWorldService.Processor<HelloWorldService.Iface>(
23
????????????????????new?HelloWorldImpl());
24
?
25
?????????????TServerSocket serverTransport =?newTServerSocket(SERVER_PORT);
26
?????????????TThreadPoolServer.Args ttpsArgs =?newTThreadPoolServer.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
import?org.apache.thrift.protocol.TCompactProtocol;
5
import?org.apache.thrift.server.TNonblockingServer;
6
import?org.apache.thrift.server.TServer;
7
import?org.apache.thrift.transport.TFramedTransport;
8
import?org.apache.thrift.transport.TNonblockingServerSocket;
9
?
10
/**
11
?* blog?http://www.micmiu.com
12
?*
13
?* @author Michael
14
?*
15
?*/
16
public?class?HelloServerDemo {
17
????public?static?final?int?SERVER_PORT =?8090;
18
?
19
????public?void?startServer() {
20
????????try?{
21
????????????System.out.println("HelloWorld TNonblockingServer start ....");
22
?
23
????????????TProcessor tprocessor =?newHelloWorldService.Processor<HelloWorldService.Iface>(
24
????????????????????new?HelloWorldImpl());
25
?
26
????????????TNonblockingServerSocket tnbSocketTransport =?newTNonblockingServerSocket(
27
????????????????????SERVER_PORT);
28
????????????TNonblockingServer.Args tnbArgs =?newTNonblockingServer.Args(
29
????????????????????tnbSocketTransport);
30
????????????tnbArgs.processor(tprocessor);
31
????????????tnbArgs.transportFactory(new?TFramedTransport.Factory());
32
????????????tnbArgs.protocolFactory(new?TCompactProtocol.Factory());
33
?
34
????????????// 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式
35
????????????TServer server =?new?TNonblockingServer(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
????public?static?void?main(String[] args) {
48
????????HelloServerDemo server =?new?HelloServerDemo();
49
????????server.startServer();
50
????}
51
?
52
}
编写客户端代码:HelloClientDemo.java
1
package?com.micmiu.thrift.demo;
2
?
3
import?org.apache.thrift.TException;
4
import?org.apache.thrift.protocol.TCompactProtocol;
5
import?org.apache.thrift.protocol.TProtocol;
6
import?org.apache.thrift.transport.TFramedTransport;
7
import?org.apache.thrift.transport.TSocket;
8
import?org.apache.thrift.transport.TTransport;
9
import?org.apache.thrift.transport.TTransportException;
10
?
11
/**
12
?* blog?http://www.micmiu.com
13
?*
14
?* @author Michael
15
?*
16
?*/
17
public?class?HelloClientDemo {
18
?
19
????public?static?final?String SERVER_IP =?"localhost";
20
????public?static?final?int?SERVER_PORT =?8090;
21
????public?static?final?int?TIMEOUT =?30000;
22
?
23
????/**
24
?????*
25
?????* @param userName
26
?????*/
27
????public?void?startClient(String userName) {
28
????????TTransport transport =?null;
29
????????try?{
30
????????????transport =?new?TFramedTransport(new?TSocket(SERVER_IP,
31
????????????????????SERVER_PORT, TIMEOUT));
32
????????????// 协议要和服务端一致
33
????????????TProtocol protocol =?new?TCompactProtocol(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
????public?static?void?main(String[] args) {
54
????????HelloClientDemo client =?new?HelloClientDemo();
55
????????client.startClient("Michael");
56
?
57
????}
58
?
59
}
客户端的测试成功,结果如下:
Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com
6.THsHaServer服务模型
半同步半异步的服务端模型,需要指定为:?TFramedTransport?数据传输的方式。
编写服务端代码: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.server.THsHaServer;
7
import?org.apache.thrift.server.TNonblockingServer;
8
import?org.apache.thrift.server.TServer;
9
import?org.apache.thrift.server.TSimpleServer;
10
import?org.apache.thrift.server.TThreadPoolServer;
11
import?org.apache.thrift.transport.TFramedTransport;
12
import?org.apache.thrift.transport.TNonblockingServerSocket;
13
import?org.apache.thrift.transport.TServerSocket;
14
?
15
/**
16
?* blog?http://www.micmiu.com
17
?*
18
?* @author Michael
19
?*
20
?*/
21
public?class?HelloServerDemo {
22
????public?static?final?int?SERVER_PORT =?8090;
23
?
24
????public?void?startServer() {
25
????????try?{
26
????????????System.out.println("HelloWorld THsHaServer start ....");
27
?
28
????????????TProcessor tprocessor =?newHelloWorldService.Processor<HelloWorldService.Iface>(
29
????????????????????new?HelloWorldImpl());
30
?
31
????????????TNonblockingServerSocket tnbSocketTransport =?newTNonblockingServerSocket(
32
????????????????????SERVER_PORT);
33
????????????THsHaServer.Args thhsArgs =?newTHsHaServer.Args(tnbSocketTransport);
34
????????????thhsArgs.processor(tprocessor);
35
????????????thhsArgs.transportFactory(new?TFramedTransport.Factory());
36
????????????thhsArgs.protocolFactory(new?TBinaryProtocol.Factory());
37
?
38
????????????//半同步半异步的服务模型
39
????????????TServer server =?new?THsHaServer(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
????public?static?void?main(String[] args) {
52
????????HelloServerDemo server =?new?HelloServerDemo();
53
????????server.startServer();
54
????}
55
?
56
}
客户端代码和上面 4 中的类似,只要注意传输协议一致以及指定传输方式为TFramedTransport。
7.异步客户端
编写服务端代码:HelloServerDemo.java
1
package?com.micmiu.thrift.demo;
2
?
3
import?org.apache.thrift.TProcessor;
4
import?org.apache.thrift.protocol.TCompactProtocol;
5
import?org.apache.thrift.server.TNonblockingServer;
6
import?org.apache.thrift.server.TServer;
7
import?org.apache.thrift.transport.TFramedTransport;
8
import?org.apache.thrift.transport.TNonblockingServerSocket;
9
?
10
/**
11
?* blog?http://www.micmiu.com
12
?*
13
?* @author Michael
14
?*
15
?*/
16
public?class?HelloServerDemo {
17
????public?static?final?int?SERVER_PORT =?8090;
18
?
19
????public?void?startServer() {
20
????????try?{
21
????????????System.out.println("HelloWorld TNonblockingServer start ....");
22
?
23
????????????TProcessor tprocessor =?newHelloWorldService.Processor<HelloWorldService.Iface>(
24
????????????????????new?HelloWorldImpl());
25
?
26
????????????TNonblockingServerSocket tnbSocketTransport =?newTNonblockingServerSocket(
27
????????????????????SERVER_PORT);
28
????????????TNonblockingServer.Args tnbArgs =?newTNonblockingServer.Args(
29
????????????????????tnbSocketTransport);
30
????????????tnbArgs.processor(tprocessor);
31
????????????tnbArgs.transportFactory(new?TFramedTransport.Factory());
32
????????????tnbArgs.protocolFactory(new?TCompactProtocol.Factory());
33
?
34
????????????// 使用非阻塞式IO,服务端和客户端需要指定TFramedTransport数据传输的方式
35
????????????TServer server =?new?TNonblockingServer(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
????public?static?void?main(String[] args) {
48
????????HelloServerDemo server =?new?HelloServerDemo();
49
????????server.startServer();
50
????}
51
?
52
}
编写客户端Client代码:HelloAsynClientDemo.java
1
package?com.micmiu.thrift.demo;
2
?
3
import?java.util.concurrent.CountDownLatch;
4
import?java.util.concurrent.TimeUnit;
5
?
6
import?org.apache.thrift.TException;
7
import?org.apache.thrift.async.AsyncMethodCallback;
8
import?org.apache.thrift.async.TAsyncClientManager;
9
import?org.apache.thrift.protocol.TCompactProtocol;
10
import?org.apache.thrift.protocol.TProtocolFactory;
11
import?org.apache.thrift.transport.TNonblockingSocket;
12
import?org.apache.thrift.transport.TNonblockingTransport;
13
?
14
importcom.micmiu.thrift.demo.HelloWorldService.AsyncClient.sayHello_call;
15
?
16
/**
17
?* blog?http://www.micmiu.com
18
?*
19
?* @author Michael
20
?*
21
?*/
22
public?class?HelloAsynClientDemo {
23
?
24
????public?static?final?String SERVER_IP =?"localhost";
25
????public?static?final?int?SERVER_PORT =?8090;
26
????public?static?final?int?TIMEOUT =?30000;
27
?
28
????/**
29
?????*
30
?????* @param userName
31
?????*/
32
????public?void?startClient(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 =?new?CountDownLatch(1);
44
????????????AsynCallback callBack =?new?AsynCallback(latch);
45
????????????System.out.println("call method sayHello start ...");
46
????????????asyncClient.sayHello(userName, callBack);
47
????????????System.out.println("call method sayHello .... end");
48
????????????boolean?wait = 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
????public?class?AsynCallback?implementsAsyncMethodCallback<sayHello_call> {
57
????????private?CountDownLatch latch;
58
?
59
????????public?AsynCallback(CountDownLatch latch) {
60
????????????this.latch = latch;
61
????????}
62
?
63
????????@Override
64
????????public?void?onComplete(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
????????public?void?onError(Exception exception) {
81
????????????System.out.println("onError :"?+ exception.getMessage());
82
????????????latch.countDown();
83
????????}
84
????}
85
?
86
????/**
87
?????* @param args
88
?????*/
89
????public?static?void?main(String[] args) {
90
????????HelloAsynClientDemo client =?new?HelloAsynClientDemo();
91
????????client.startClient("Michael");
92
?
93
????}
94
?
95
}
先运行服务程序,再运行客户端程序,测试结果如下:
Client start ..... call method sayHello start ... call method sayHello .... end onComplete AsynCall result =:Hi,Michael welcome to my blog www.micmiu.com latch.await =:true startClient end.
————