1. 程式人生 > >Thrift——入門Demo(Java)

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路徑下:

image

在cmd中輸入:thrift -version ,檢視是否安裝配置成功

image

出現版本號,安裝成功。

定義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

image

可以看到生成了一個名為gen-java的資料夾,其中就是生成的程式碼,開啟後可以看到層級目錄下有:

image

程式碼片段:

/**
 * 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……

image

客戶端啟動

客戶端步驟:

  • 建立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");
    }   
}

控制檯輸出

image

客戶端成功收到了服務端返回的請求結果,通訊完成