轉載自 https://www.cnblogs.com/newboys/p/9366762.html
什麼是thrift?
簡單來說,是Facebook公佈的一款開源跨語言的RPC框架.
那麼問題來了.
什麼是RPC框架?
RPC全稱爲Remote Procedure Call,意爲遠程過程調用.
假設有兩臺服務器A,B.A服務器上部署着一個應用a,B服務器上部署着一個應用b,現在a希望能夠調用b應用的某個函數(方法),但是二者不在同一個進程內,不能直接調用,就需要通過網絡傳輸,在AB服務器之間建一條網絡傳輸通道,a把參數傳過去,b接收到參數調用自己的方法,得到結果,再通過網絡傳回給a,簡單講就是A通過網絡來調用B的過程.這個過程要涉及的東西很多,比如多線程,Socket,序列化反序列化,網絡I/O,很複雜,於是牛掰的程序員把這些封裝起來做成一套框架,供大家使用,就是RPC框架.
thrift的跨語言特型
thrift通過一箇中間語言IDL(接口定義語言)來定義RPC的數據類型和接口,這些內容寫在以.thrift結尾的文件中,然後通過特殊的編譯器來生成不同語言的代碼,以滿足不同需要的開發者,比如java開發者,就可以生成java代碼,c++開發者可以生成c++代碼,生成的代碼中不但包含目標語言的接口定義,方法,數據類型,還包含有RPC協議層和傳輸層的實現代碼.
thrift的協議棧結構
thrift是一種c/s的架構體系.在最上層是用戶自行實現的業務邏輯代碼.第二層是由thrift編譯器自動生成的代碼,主要用於結構化數據的解析,發送和接收。TServer主要任務是高效的接受客戶端請求,並將請求轉發給Processor處理。Processor負責對客戶端的請求做出響應,包括RPC請求轉發,調用參數解析和用戶邏輯調用,返回值寫回等處理。從TProtocol以下部分是thirft的傳輸協議和底層I/O通信。TProtocol是用於數據類型解析的,將結構化數據轉化爲字節流給TTransport進行傳輸。TTransport是與底層數據傳輸密切相關的傳輸層,負責以字節流方式接收和發送消息體,不關注是什麼數據類型。底層IO負責實際的數據傳輸,包括socket、文件和壓縮數據流等。
1 首先,在官網下載安裝包http://thrift.apache.org/download , windows下下載Thrift compiler for Windows (thrift-0.11.0.exe),放到某個目錄下,修改名稱爲 thrift.exe 。
2 添加thrift.exe 目錄路徑到path 環境變量
3 使用。
3.1 定義thrift的接口文件,文件名稱爲Apple.thrift
1
2
3
4
5
6
|
namespace java service.demo
service Apple{
string appleString( 1 :string para);
i32 appleAdd( 1 :i32 para);
i32 appleMult( 2 :i32 para1,i32 para2);
}
|
3.2 編譯Apple.thrift文件,生成接口文件,
命令: thrift -r -gen java Apple.thrift,會生成一個Apple.java 文件,把文件放入項目中,
3.3 新建mavne 項目,
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.10.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
3.4 新建接口實現類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package service.demo;
import org.apache.thrift.TException;
public class AppleServiceImpl implements Apple.Iface{
@Override
public String appleString(String para) throws TException {
return "apple print hello " + para;
}
@Override
public int appleAdd( int para) throws TException {
// TODO Auto-generated method stub
return para+ 10 ;
}
@Override
public int appleMult( int para1, int para2) throws TException {
// TODO Auto-generated method stub
return para1-para2;
}
}
|
3.5 服務端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package service.demo;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
public class AppleServiceServer {
public static void main(String[] args) throws TTransportException {
System.out.println( "apple 服務端開啓。。" );
TProcessor tprocessor = new Apple.Processor<Apple.Iface>( new AppleServiceImpl());
TServerSocket serverTransport = new TServerSocket( 9000 );
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory( new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
}
}
|
3.6 客戶端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package service.demo;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import service.demo.Apple.Client;
public class AppleServiceClient {
public static void main(String[] args) {
System.out.println( "客戶端開始。。" );
TTransport transport = null ;
try {
transport = new TSocket( "localhost" , 9000 , 3000 );
TProtocol protocol = new TBinaryProtocol(transport);
Client client = new Apple.Client(protocol);
transport.open();
String result = client.appleString( "abc" );
System.out.println( "服務端返回 。 " + result);
int a = client.appleAdd( 8 );
int b = client.appleMult( 29 , 3 );
System.out.println( "a= " + a + " b=" +b);
} catch (TTransportException e){
e.printStackTrace();
} catch (TException e){
e.printStackTrace();
} finally {
if ( null !=transport){
transport.close();
}
}
}
}
|
3.7 整個項目
3.8 啓動服務端和客戶端代碼,
執行結果
客戶端開始。。
Received 1
服務端返回 。 apple print hello abc
Received 2
Received 3
a= 18 b=26