1. 程式人生 > >thrift使用和源碼分析

thrift使用和源碼分析

服務 tac tex exce hub oid 目錄 圖片 cli

1 前言

thrift的官方文檔比較差,很多細節沒有介紹清楚,比如require、optional和default字段的區別是什麽,為什麽字段前面要寫序號等,帶著這些疑問,我們需要閱讀生成的源碼來了解具體細節。另外thrift的非官方文檔可以參考這篇:http://diwakergupta.github.io/thrift-missing-guide

2 network stack

thrif的網絡棧在官網已經介紹的比較清楚了,分為4層,從下往上依次是:

技術分享圖片

  1. Transport。提供網絡IO的簡單抽象
  2. Protocol。用於編解碼,將底層的字節編碼成二進制、JSON等;Protocol層用於對模式編碼以及負責序列化
  3. Processor。封裝了從Protocol讀寫的功能,可以理解為用戶的業務邏輯所在地
  4. Server。代碼一個服務端,將Transport、Protocol、Processor整合起來,等待請求到來並處理

3 簡單使用

3.1 thrift安裝

thrift的安裝按照官網的教程或者網上其他教程來就行了,這裏安裝的是thrift的0.8.0版本, 安裝完後可以使用命令查看安裝的thrift版本

thrift -version

3.2 編寫IDL

創建文件mythrift.thrift,在裏面編寫如下內容

namespace java com.learn.learnthrift

 struct Stu {
 1:i32 name = 13
 2:required i32 age
 3:optional i32 height = 23
 }

 struct Teacher {
 1:string name = "13"
 2:required string age = "14"
 3:optional string height = "15"
 }

 service MyService {
     void printStu(1:Stu stu, 2:Teacher teacher)
     void printStu2(1:Stu stu, 2:Teacher teacher)
 }

3.3 生成java代碼

運行命令,生成java代碼,然後將生成的代碼拷貝進項目即可使用,其中mythrift.thrift就是剛才我們編寫的IDL文件。運行命令後會在mythrift.thrift所在的目錄生成gen-javabean文件夾,其內容就是我們生成java文件

thrift --gen java:beans mythrift.thrift

生成的文件如下:

技術分享圖片

3.4 編寫代碼

將生成的代碼copy到項目中,其中紅框框起來的是thrift生成的文件,其他的是需要我們編寫的代碼

技術分享圖片

DemoClient.java

public class DemoClient {
    public static void main(String[] args) throws Exception{
        // 創建Transport
        TTransport transport = new TSocket("localhost", 9090, 5000);
        //創建protocol
        TProtocol protocol = new TBinaryProtocol(transport);

        //創建客戶端
        MyService.Client client = new MyService.Client(protocol);
        transport.open();

        Stu stu = new Stu();
        stu.setAge(23);

        Teacher teacher = new Teacher("jack", "32");
        client.printStu(stu, teacher);

        transport.close();
    }
}

DemoServer.java

public class DemoServer {
    public static void main(String[] args) throws Exception{
        // 創建processor
        TProcessor tProcessor = new MyService.Processor<MyService.Iface>(new MyServiceImpl());
        //創建protocol
        TProtocolFactory tProtocolFactory = new TBinaryProtocol.Factory();

        // 創建transport, TServerSocket繼承自TTransport
        TServerSocket tServerSocket = new TServerSocket(9090);
        //創建server參數
        TServer.Args tArgs = new TServer.Args(tServerSocket);
        tArgs.processor(tProcessor);
        tArgs.protocolFactory(tProtocolFactory);

        // 創建TServer
        TServer tServer = new TSimpleServer(tArgs);
        tServer.serve();
    }
}

MyServiceImpl.java

public class MyServiceImpl implements MyService.Iface {
    @Override
    public void printStu(Stu stu, Teacher teacher) throws TException {
        System.out.println(stu);
        System.out.println("name:" + stu.getName());
        System.out.println("age:" + stu.getAge());
        System.out.println("height:" + stu.getHeight());

        System.out.println("nameset: " + stu.isSetName());
        System.out.println("ageset: " + stu.isSetAge());
        System.out.println("height: " + stu.isSetHeight());
    }

    @Override
    public void printStu2(Stu stu, Teacher teacher) throws TException {
        System.out.println("printStu2 : " + stu);
    }
}

然後分別運行DemoServer和DemoClient就可以了,這就是簡單的RPC通信

4 源碼閱讀

thrift使用和源碼分析