Thrift入門初探--thrift安裝及java入門實例


  公司的一些平台服務框架底層封裝了thrift提供服務,最近項目不是很緊,於是研究了一下,剛剛入門,理解得不深,寫這篇博文來整理一下思路.

什么是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、文件和壓縮數據流等。

MAC OS下thrift的下載與安裝

  我的電腦是mac,第一次安裝也碰到了一些問題,所以有必要記錄一下.

  首先,在官網下載安裝包http://thrift.apache.org/download 目前官網是0.10.0版本.下載完之后解壓到想要安裝的目錄.

  進入根目錄:

step1:cd thrift-0.10.0 step2:./configure
step3:make step4:make install

  安裝的時候,第二步出現了問題,提示:

Bison version 2.5 or higher must be installed on the system!

  原因是Bison版本過低,mac默認安裝的版本是2.3,因此需要安裝最新版的Bison,命令行輸入:brew install bison安裝最新版bison,如果你的命令行反饋:Command not found,很可能是因為你沒裝homebrew,命令行輸入:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

  等待安裝完homebrew就可以安裝bison了,最新版本3.0.4安裝完以后,執行第二步,發現依然提示上面那個警告,原因是因為它讀取的仍然是默認的bison,於是找到系統安裝的bison目錄,我的mac是

/Library/Developer/CommandLineTools/usr/bin/bison,解決方法也比較簡單,可以先將這個目錄下的bison名字改一下,再將最新版的bison復制進來,於是,在bin目錄下,執行命令:

sudo mv bison bison111

sudo cp /usr/local/opt/bison/bin/bison  /Library/Developer/CommandLineTools/usr/bin/

  現在,再按照上面的步驟進行下去,就可以正確安裝thrift了.

進入thrift大門的第一個java小實例

   1,創建一個服務Hello,創建文件Hello.thrift,代碼如下:

namespace java service.demo
service Hello{
    string helloString(1:string para)
}

  這里定義了一個名為helloString的方法,入參和返回值都是一個string類型的參數.

   2,終端進入Hello.thrift所在目錄,執行命令:

thrift -r -gen java Hello.thrift

  發現在當前目錄下多了一個gen-java的目錄,里面的有一個Hello.java的文件.這個java文件包含Hello服務的接口定義Hello.Iface,以及服務調用的底層通信細節,包括客戶端的調用邏輯Hello.Client以及服務端的處理邏輯Hello.Processor,

   3,創建一個Maven管理的Java項目,pom.xml中添加相關的依賴,並將Hello.java文件復制到項目中:

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

       4,創建HelloServiceImpl實現Hello.Iface接口:

package service.demo;
import org.apache.thrift.TException;
/**
 * @author yogo.wang
 * @date 2017/02/21-下午2:13.
 */
public class HelloServiceImpl implements Hello.Iface {
    public String helloString(String para) throws TException {
        return "result:"+para;
    }
}

  5,創建服務端實現代碼HelloServiceServer,把HelloServiceImpl作為一個具體的處理器傳遞給Thrift服務器:

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;

/**
 * @author yogo.wang
 * @date 2017/02/21-下午2:15.
 */
public class HelloServiceServer {
    /**
     * 啟動thrift服務器
     * @param args
     */
    public static void main(String[] args) {
        try {
            System.out.println("服務端開啟....");
            TProcessor tprocessor = new Hello.Processor<Hello.Iface>(new HelloServiceImpl());
            // 簡單的單線程服務模型
            TServerSocket serverTransport = new TServerSocket(9898);
            TServer.Args tArgs = new TServer.Args(serverTransport);
            tArgs.processor(tprocessor);
            tArgs.protocolFactory(new TBinaryProtocol.Factory());
            TServer server = new TSimpleServer(tArgs);
            server.serve();
            }catch (TTransportException e) {
            e.printStackTrace();
        }
    }
}

  6,創建客戶端實現代碼HelloServiceClient,調用Hello.client訪問服務端的邏輯實現:

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;

/**
 * @author yogo.wang
 * @date 2017/02/21-下午2:35.
 */
public class HelloServiceClient {

    public static void main(String[] args) {
        System.out.println("客戶端啟動....");
        TTransport transport = null;
        try {
            transport = new TSocket("localhost", 9898, 30000);
            // 協議要和服務端一致
            TProtocol protocol = new TBinaryProtocol(transport);
            Hello.Client client = new Hello.Client(protocol);
            transport.open();
            String result = client.helloString("哈哈");
            System.out.println(result);
        } catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (null != transport) {
                transport.close();
            }
        }
    }
}

  全部工作完成后,下面來測試一下,先執行服務端main方法,在執行客戶端main方法,會在客戶端控制台打印出:result:哈哈.

相關博文:

Thrift入門初探(2)--thrift基礎知識詳解

參考文章:

     Apache Thrift - 可伸縮的跨語言服務開發框架

     Thrift RPC框架介紹


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM