Thrift基本流程
阿新 • • 發佈:2018-12-03
1. Thrift類介紹
Thrift程式碼包(位於thrift-0.6.1/lib/cpp/src)有以下幾個目錄:
concurrency:併發和時鐘管理方面的庫
processor:Processor相關類
protocal:Protocal相關類
transport:transport相關類
server:server相關類
負責資料傳輸,有以下幾個可用類:
TFileTransport:檔案(日誌)傳輸類,允許client將檔案傳給server,允許server將收到的資料寫到檔案中;
THttpTransport:採用Http傳輸協議進行資料傳輸;
TSocket:採用TCP Socket進行資料傳輸;
TZlibTransport:壓縮後對資料進行傳輸,或者將收到的資料解壓。 下面幾個類主要是對上面幾個類地裝飾(採用了裝飾模式),以提高傳輸效率。
TBufferedTransport:對某個Transport物件操作的資料進行buffer,即從buffer中讀取資料進行傳輸,或者將資料直接寫入buffer;
TFramedTransport:同TBufferedTransport類似,也會對相關資料進行buffer,同時,它支援定長資料傳送和接收;
TMemoryBuffer:從一個緩衝區中讀寫資料。
1.2 Protocol類(what is transmitted?)
負責資料編碼,主要有以下幾個可用類:
TBinaryProtocol:二進位制編碼
TJSONProtocol:JSON編碼
TCompactProtocol:密集二進位制編碼
TDebugProtocol:以使用者易讀的方式組織資料 1.3 Server類(providing service for clients)
TSimpleServer:簡單的單執行緒伺服器,主要用於測試
TThreadPoolServer:使用標準阻塞式IO的多執行緒伺服器
TNonblockingServer:使用非阻塞式IO的多執行緒伺服器,TFramedTransport必須使用該型別的server
1.5 物件序列化和反序列化
Client編寫的方法分為以下幾個步驟:
(1) 定義TTransport,為你的client設定傳輸方式(如socket, http等)。
(2) 定義Protocal,使用裝飾模式(Decorator設計模式)封裝TTransport,為你的資料設定編碼格式(如二進位制格式,JSON格式等)
(3) 例項化client物件,呼叫服務介面。
說明:如果使用者在thrift檔案中定義了一個叫${server_name}的service,則會生成一個叫${server_name}Client的物件。 2.2 Server端程式碼編寫
(1) 定義一個TProcess,這個是thrift根據使用者定義的thrift檔案自動生成的類
(2) 使用TServerTransport獲得一個TTransport
(3) 使用TTransportFactory,可選地將原始傳輸轉換為一個適合的應用傳輸(典型的是使用TBufferedTransportFactory)
(4) 使用TProtocolFactory,為TTransport建立一個輸入和輸出
(5) 建立TServer物件(單執行緒,可以使用TSimpleServer;對於多執行緒,使用者可使用TThreadPoolServer或者TNonblockingServer),呼叫它的server()函式。
說明:thrift會為每一個帶service的thrift檔案生成一個簡單的server程式碼(樁), 3.示例:
1. thrift生成程式碼
建立Thrift檔案:G:\test\thrift\demoHello.thrift ,內容如下:
namespace java com.micmiu.thrift.demo service HelloWorldService { string sayHello(1:string username) } |
<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 package com.micmiu.thrift.demo;import org.apache.thrift.TException;
public class HelloWorldImpl implements HelloWorldService.Iface {
public HelloWorldImpl() {
}
@Override
public String sayHello(String username) throws TException {
return "Hi," + username + " welcome to my blog www.micmiu.com";
}
}
3.TSimpleServer服務端
簡單的單執行緒服務模型,一般用於測試。
編寫服務端server程式碼:HelloServerDemo.java package com.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;
import org.apache.thrift.protocol.TSimpleJSONProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
public class HelloServerDemo {
public static final int SERVER_PORT = 8090;
public void startServer() {
try {
System.out.println("HelloWorld TSimpleServer start ....");
TProcessor tprocessor = new HelloWorldService.Processor<HelloWorldService.Iface>(
new HelloWorldImpl());
// HelloWorldService.Processor<HelloWorldService.Iface> tprocessor =
// new HelloWorldService.Processor<HelloWorldService.Iface>(
// new HelloWorldImpl());
// 簡單的單執行緒服務模型,一般用於測試
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
// tArgs.protocolFactory(new TCompactProtocol.Factory());
// tArgs.protocolFactory(new TJSONProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
} catch (Exception e) {
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
HelloServerDemo server = new HelloServerDemo();
server.startServer();
}
} 編寫客戶端Client程式碼:HelloClientDemo.java package com.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;
public class HelloClientDemo {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 8090;
public static final int TIMEOUT = 30000;
/**
*
* @param userName
*/
public void startClient(String userName) {
TTransport transport = null;
try {
transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
// 協議要和服務端一致
TProtocol protocol = new TBinaryProtocol(transport);
// TProtocol protocol = new TCompactProtocol(transport);
// TProtocol protocol = new TJSONProtocol(transport);
HelloWorldService.Client client = new HelloWorldService.Client(
protocol);
transport.open();
String result = client.sayHello(userName);
System.out.println("Thrify client result =: " + result);
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
} finally {
if (null != transport) {
transport.close();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
HelloClientDemo client = new HelloClientDemo();
client.startClient("Michael");
}
}
先執行服務端程式,日誌如下:
HelloWorld TSimpleServer start .... |
再執行客戶端呼叫程式,日誌如下:
Thrify client result =: Hi,Michael welcome to my blog www.micmiu.com |
測試成功,和預期的返回資訊一致。
總結:Server端和client端編碼基本步驟1.服務端編碼基本步驟:
- 實現服務處理介面impl
- 建立TProcessor
- 建立TServerTransport
- 建立TProtocol
- 建立TServer
- 啟動Server
2.客戶端編碼基本步驟:
- 建立Transport
- 建立TProtocol
- 基於TTransport和TProtocol建立 Client
- 呼叫Client的相應方法
http://dongxicheng.org/search-engine/thrift-rpc/