thrift使用

1、什麼是thriftjava

  Thrift是一種接口描述語言和二進制通信協議,它被用來定義和建立跨語言的服務。它被看成一個遠程過程調用(RPC)框架來使用,是由FaceBook爲「大規模跨語言服務開發」而開發的。它經過一個代碼生成引擎聯合了一個軟件棧,來建立不一樣程度的、無縫的跨平臺高效服。後來捐獻給apache組織了。apache

 

2、thrift的架構  服務器

Thrift包含一套完整的棧來建立客戶端和服務端程序。頂層部分是由Thrift定義生成的代碼。而服務則由這個文件客戶端和處理器代碼生成。在生成的代碼裏會建立不一樣於內建類型的數據結構,並將其做爲結果發送。協議和傳輸層是運行時庫的一部分。有了Thrift,就能夠定義一個服務或改變通信和傳輸協議,而無需從新編譯代碼。除了客戶端部分以外,Thrift還包括服務器基礎設施來集成協議和傳輸,如阻塞、非阻塞及多線程服務器。棧中做爲I/O基礎的部分對於不一樣的語言則有不一樣的實現。
Thrift支持衆多通信協議:
  • TBinaryProtocol – 一種簡單的二進制格式,簡單,但沒有爲空間效率而優化。比文本協議處理起來更快,但更難於調試。
  • TCompactProtocol – 更緊湊的二進制格式,處理起來一般一樣高效。
  • TDebugProtocol – 一種人類可讀的文本格式,用來協助調試。
  • TDenseProtocol – 與TCompactProtocol相似,將傳輸數據的元信息剝離。
  • TJSONProtocol – 使用JSON對數據編碼。
  • TSimpleJSONProtocol – 一種只寫協議,它不能被Thrift解析,由於它使用JSON時丟棄了元數據。適合用腳本語言來解析。
支持的傳輸協議有:
  • TFileTransport – 該傳輸協議會寫文件。
  • TFramedTransport – 當使用一個非阻塞服務器時,要求使用這個傳輸協議。它按幀來發送數據,其中每一幀的開頭是長度信息。
  • TMemoryTransport – 使用存儲器映射輸入輸出。(Java的實現使用了一個簡單的ByteArrayOutputStream。)
  • TSocket – 使用阻塞的套接字I/O來傳輸。
  • TZlibTransport – 用Zlib執行壓縮。用於鏈接另外一個傳輸協議。
Thrift還提供衆多的服務器,包括:
  • TNonblockingServer – 一個多線程服務器,它使用非阻塞I/O(Java的實現使用了NIO通道)。TFramedTransport必須跟這個服務器配套使用。
  • TSimpleServer – 一個單線程服務器,它使用標準的阻塞I/O。測試時頗有用。
  • TThreadPoolServer – 一個多線程服務器,它使用標準的阻塞I/O。

 

3、thrift的使用數據結構

  1.下載並安裝thrift.exe,而後配置環境變量,使用thrift -version 來驗證是否安裝成功多線程

  2.編寫.thrift文件架構

  

//名稱空間,用來隔離代碼,防止數據類型定義中名字衝突
namespace java netty_thrift

//引入其餘thrift文件
//include "test.thrift"

/**
數據類型定義,經過typedef將thrift中的類型和java中的類型對應起來,而後直接使用java中的數據類型,方便理解
下面就是thrift中使用的基本數據類型
*/
typedef i16 short
typedef i32 int
typedef i64 long
typedef bool boolean
typedef string String
typedef double double

//定義常量
//const int CONSTANT_A = 12345

/**
定義結構
1.每一個屬性都有惟一一個正整數標識符
2.每一個屬性均可以標記爲optional和required
3.每一個結構體均可以包含其餘結構體
4.每一個屬性都有默認值
5.
*/
struct Person{
    1: optional String username
    2: optional int age
    3: optional boolean married
}


//異常定義
exception DataException{
    1: optional String message
    2: optional String callStack
    3: optional String date
}

//服務定義
service PersonService{

    Person getPersonByName(1: required String username) throws (1: DataException dataException),
    
    void savePerson(1: required Person person)
}


enum TweetType {//僅僅是做爲一個例子,後面生成代碼時沒有用到
 
TWEET,         // 編譯器默認從1開始賦值
RETWEET = 2,  // 能夠賦予某個常量某個整數
DM = 0xa,     //容許常量是十六進制整數
REPLY         // 末尾沒有逗號
}        

 

  3.生成java代碼框架

    使用命令行thrift -gen java D:\WorkSpace1\netty\src\netty_thrift\data.thrift   生成的文件在執行命令時所在的目錄。socket

 

  4.編寫服務端和客戶端的代碼ide

    

public class Server {

    public static void main(String[] args) throws TTransportException {
        TNonblockingServerSocket socket = new TNonblockingServerSocket(9999);
        org.apache.thrift.server.THsHaServer.Args args3 = new THsHaServer.Args(socket);
        Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl());
        
        args3.protocolFactory(new TCompactProtocol.Factory());
        args3.transportFactory(new TFramedTransport.Factory());
        args3.processorFactory(new TProcessorFactory(processor));
        
        THsHaServer server = new THsHaServer(args3);
        server.serve();
    }

}

 

 

public class PersonServiceImpl implements PersonService.Iface {

    @Override
    public Person getPersonByName(String username) throws DataException, TException {
        Person p = new Person();
        p.setUsername(username);
        p.setAge(28);
        p.setMarried(false);
        return p;
    }

    @Override
    public void savePerson(Person person) throws TException {
        System.out.println(person);
    }

}

 

public class Client {

    public static void main(String[] args) throws DataException, TException {
        TFramedTransport tFramedTransport = new TFramedTransport(new TSocket("localhost",9999));
        TProtocol protocol = new TCompactProtocol(tFramedTransport);
         netty_thrift.PersonService.Client client = new PersonService.Client(protocol);
         tFramedTransport.open();
        
        Person person = client.getPersonByName("kyle");
        System.out.println(person);
        
        Person p = new Person();
        p.setUsername("xiaoming");
        p.setAge(24);
        p.setMarried(false);
        client.savePerson(p);
        
    }
}
相關文章
相關標籤/搜索