(我覺得后兩種模式的文檔較少,需要一些教程類型的介紹,因此是本文的動機。) 為了輕松地遵循本教程,您對Thrift體系結構(由傳輸,協議和處理器組成)有基本的了解是有益的。 (可以在[1]上找到好的論文)。 在這里,我將使用Thrift 0.7版和Thrift的Java綁定。
節儉安裝
可以在http://wiki.apache.org/thrift/ThriftInstallation中找到安裝說明。
總結Ubuntu安裝步驟。
1.安裝所需的依賴項。
$ sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g ++ libssl-dev
2.轉到安裝根目錄。 3. $ ./configure 4. $ make 5.成為超級用戶并 $進行安裝
現在讓我們繼續創建服務并使用它。
服務定義
此處定義了具有簡單算術運算的服務。 請注意,使用typedef指令為基本類型i64和i32聲明備用名稱。 在名為“ 算術.thrift ”的文件中添加以下內容。
namespace java tutorial.arithmetic.gen // define namespace for java codetypedef i64 long
typedef i32 int
service ArithmeticService { // defines simple arithmetic service
long add(1:int num1, 2:int num2),
long multiply(1:int num1, 2:int num2),
}
代碼將在“ tutorial.arithmetic.gen ”包下生成。
現在,使用以下命令行生成Java代碼。
$ thrift –gen java算術.thrift
將生成源tutorial.arithmetic.gen.ArithmeticService.java 。
封鎖模式
讓我們創建一個阻塞模式的服務器和一個使用服務的客戶端。
首先,我們需要使用生成的服務框架來實現服務。 要實現的接口是ArithmeticService.Iface。
public class ArithmeticServiceImpl implements ArithmeticService.Iface {public long add(int num1, int num2) throws TException {return num1 + num2;}public long multiply(int num1, int num2) throws TException {return num1 * num2;}}
現在,讓我們創建Thrift服務器,該服務器將請求此服務。 請記住,這是一臺阻塞服務器,因此執行I / O的服務器線程將等待。
public class Server {private void start() {try {TServerSocket serverTransport = new TServerSocket(7911);ArithmeticService.Processor processor = new ArithmeticService.Processor(new ArithmeticServiceImpl());TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));System.out.println("Starting server on port 7911 ...");server.serve();} catch (TTransportException e) {e.printStackTrace();}}public static void main(String[] args) {Server srv = new Server();srv.start();}}
這里使用了TThreadPoolServer實現,該實現將利用線程池來處理傳入的請求。
現在讓我們編寫客戶端。
public class ArithmeticClient {private void invoke() {TTransport transport;try {transport = new TSocket("localhost", 7911);TProtocol protocol = new TBinaryProtocol(transport);ArithmeticService.Client client = new ArithmeticService.Client(protocol);transport.open();long addResult = client.add(100, 200);System.out.println("Add result: " + addResult);long multiplyResult = client.multiply(20, 40);System.out.println("Multiply result: " + multiplyResult);transport.close();} catch (TTransportException e) {e.printStackTrace();} catch (TException e) {e.printStackTrace();}}public static void main(String[] args) {ArithmeticClient c = new ArithmeticClient();c.invoke();}
}
TBinaryProtocol用于對服務器和客戶端之間傳輸的數據進行編碼。 現在啟動服務器,并使用客戶端調用服務以生成結果。
非阻塞模式
現在讓我們創建一個非阻塞服務器,該服務器在下面使用Java非阻塞I / O。 我們可以使用與以前相同的服務實現(ArithmeticServiceImpl)。
public class NonblockingServer {private void start() {try {TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(7911);ArithmeticService.Processor processor = new ArithmeticService.Processor(new ArithmeticServiceImpl());TServer server = new TNonblockingServer(new TNonblockingServer.Args(serverTransport).processor(processor));System.out.println("Starting server on port 7911 ...");server.serve();} catch (TTransportException e) {e.printStackTrace();}}public static void main(String[] args) {NonblockingServer srv = new NonblockingServer();srv.start();}
}
在這里,使用TNonblockingServerSocket封裝了ServerSocketChannel。
非阻塞客戶端的代碼如下。
public class NonblockingClient {private void invoke() {TTransport transport;try {transport = new TFramedTransport(new TSocket("localhost", 7911));TProtocol protocol = new TBinaryProtocol(transport);ArithmeticService.Client client = new ArithmeticService.Client(protocol);transport.open();long addResult = client.add(100, 200);System.out.println("Add result: " + addResult);long multiplyResult = client.multiply(20, 40);System.out.println("Multiply result: " + multiplyResult);transport.close();} catch (TTransportException e) {e.printStackTrace();} catch (TException e) {e.printStackTrace();}}public static void main(String[] args) {NonblockingClient c = new NonblockingClient();c.invoke();}}
注意使用TFramedTransport包裝正常的TSocket傳輸。 非阻塞服務器要求客戶端使用TFramedTransport,它將對通過網絡發送的數據進行框架化。 啟動服務器并使用客戶端發送請求。 您將看到與以前相同的結果,這次使用非阻止模式。
異步模式
我們可以編寫異步客戶端來調用Thrift服務。 需要注冊一個回調,該回調將在請求成功完成時被調用。 阻塞模式服務器在異步客戶端上不起作用(方法調用返回的響應為空)(可能是因為我們在客戶端使用TNonblockingSocket。請參見ArithmeticService.AsyncClient的構造。因此這可能是正確的行為)。 非阻塞模式服務器似乎可以正常工作。 因此,您可以將早期版本的非阻塞服務器與下面顯示的客戶端一起使用。
public class AsyncClient {private void invoke() {try {ArithmeticService.AsyncClient client = new ArithmeticService.AsyncClient(new TBinaryProtocol.Factory(), new TAsyncClientManager(),new TNonblockingSocket("localhost", 7911));client.add(200, 400, new AddMethodCallback());client = new ArithmeticService.AsyncClient(new TBinaryProtocol.Factory(), new TAsyncClientManager(),new TNonblockingSocket("localhost", 7911));client.multiply(20, 50, new MultiplyMethodCallback());} catch (TTransportException e) {e.printStackTrace();} catch (TException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {AsyncClient c = new AsyncClient();c.invoke();}class AddMethodCallbackimplements AsyncMethodCallback<ArithmeticService.AsyncClient.add_call> {public void onComplete(ArithmeticService.AsyncClient.add_call add_call) {try {long result = add_call.getResult();System.out.println("Add from server: " + result);} catch (TException e) {e.printStackTrace();}}public void onError(Exception e) {System.out.println("Error : ");e.printStackTrace();}}class MultiplyMethodCallbackimplements AsyncMethodCallback<ArithmeticService.AsyncClient.multiply_call> {public void onComplete(ArithmeticService.AsyncClient.multiply_call multiply_call) {try {long result = multiply_call.getResult();System.out.println("Multiply from server: " + result);} catch (TException e) {e.printStackTrace();}}public void onError(Exception e) {System.out.println("Error : ");e.printStackTrace();}}}
已經定義了兩個回調,分別與服務的每個操作相對應。 請注意,這兩個調用使用了兩個客戶端實例。 每個調用都需要一個單獨的客戶端實例,否則客戶端將因以下異常而失敗
“ 線程“ main ”中的異常java.lang.IllegalStateException:客戶端當前正在執行另一種方法:tutorial.arithmetic.gen.ArithmeticService $ AsyncClient $ add_call “
因此,本文以不同的操作模式總結了我在Thrift上的快速入門。 希望有人會覺得有用。 如有任何建議或更正,請隨時發表評論。
[1] http://thrift.apache.org/static/thrift-20070401.pdf參考:來自JCG合作伙伴的 Apache Thrift快速入門教程 ? Source Open博客中的Buddhika Chamith。
翻譯自: https://www.javacodegeeks.com/2012/03/apache-thrift-quickstart-tutorial.html