Thrift——入門Demo(Java)
概述
Thrift最初由Facebook研發,主要用於各個服務之間的RPC通訊。
Thrift是一個典型的CS(客戶端/服務端)結構,客戶端和服務端可以使用不同的語言開發。
那麼它是如何實現使用不同的語言開發呢?答案:用一種中間語言來關聯客戶端和服務端的語言。
這種語言就是IDL(Interface Description Language)。將這個IDL作為輸入檔案,編譯器就可以生成程式碼(支援多種),即RPC客戶端和伺服器通訊的無縫跨程式語言。
安裝
下載官方連結:http://thrift.apache.org/download
將下載好的thrift-0.10.0 .exe檔案命名為thrift .exe,放在D盤下的一個Thtift資料夾中,
為了更方便使用命令,將目錄加入到系統Path路徑下:
在cmd中輸入:thrift -version ,檢視是否安裝配置成功
出現版本號,安裝成功。
定義thrift——IDL檔案
IDL檔案有許多資料型別
- 結構體型別: struct:定義公共的物件,類似於 C 語 言中的結構體定義,在 Java 中是一個 JavaBean
- 容器型別:
list:對應 Java 的 ArrayList
set:對應 Java 的 HashSet
map:對應 Java 的 HashMap - 異常型別: exception:對應 Java 的 Exception
- 服務型別: service:對應服務的類
這裡僅僅定義一個服務。
thrift定義服務相當於Java中建立Interface,建立的service通過程式碼生成命令生成客戶端和服務端的框架程式碼。
定義形式如下(helloworld.thrift,注意字尾!):
namespace java com.test
service HelloWorldService{
string sayHello(1:string name)
}
——namespace 相當於Java中的package。
在 cmd中 輸入命令: thrift -gen java helloworld.thrift
可以看到生成了一個名為gen-java的資料夾,其中就是生成的程式碼,開啟後可以看到層級目錄下有:
程式碼片段:
/**
* Autogenerated by Thrift Compiler (0.10.0)
*
* DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
* @generated
*/
package com.test;
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)", date = "2017-07-18")
public class HelloWorldService {
public interface Iface {
public java.lang.String sayHello(java.lang.String name) throws org.apache.thrift.TException;
}
建立專案
建立一個Maven工程,引入依賴,可在Maven依賴中看到引入的相關Jar包
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.10.0</version>
</dependency>
服務端實現與啟動
服務端相關操作的步驟如下:
- 實現服務處理介面Impl
- 建立TProcessor
- 建立TServerTransport
- 建立TProtocol
- 建立TServer
- 啟動Server
服務端實現
package com.test;
import org.apache.thrift.TException;
public class HelloWorldImpl implements HelloWorldService.Iface{
public HelloWorldImpl(){
}
public String sayHello(String name) throws TException {
return "Hi," +name + " welcome !";
}
}
服務端啟動
package com.test;
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;
public class HelloServer {
public static final int SERVER_PORT = 8090;
public void startServer(){
System.out.println("Server is Runing......");
TProcessor tprocessor = new HelloWorldService.Processor(new HelloWorldImpl());
//簡單的單執行緒服務模型,一般用於測試
try {
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
} catch (Exception e) {
System.out.println("Server start error!");
e.printStackTrace();
}
}
public static void main(String[] args) {
HelloServer server = new HelloServer();
server.startServer();
}
}
執行上面的啟動類,控制檯輸出:Server is Runing……
客戶端啟動
客戶端步驟:
- 建立Transport
- 建立TProtocol
- 基於TTransport和TProtocol建立 Client
- 呼叫Client的相應方法
客戶端啟動
package com.test;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
public class HelloClient {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 8090;
public static final int TIMEOUT = 30000;
public void startClient(String userName){
TTransport transport = null;
try {
transport = new TSocket(SERVER_IP,SERVER_PORT,TIMEOUT);
//協議要和服務端一致
TProtocol protocol = new TBinaryProtocol(transport);
HelloWorldService.Client client = new HelloWorldService.Client(protocol);
transport.open();
String result = client.sayHello(userName);
System.out.println("Thrift client result is:"+result);
} catch (Exception e) {
System.out.println("client is error!");
}finally{
if(null != transport){
transport.close();
}
}
}
public static void main(String[] args) {
HelloClient client = new HelloClient();
client.startClient("Z Yong");
}
}
控制檯輸出
客戶端成功收到了服務端返回的請求結果,通訊完成。