thrift中的概念

Thrift的網絡棧apache

Apache Thrift的網絡棧的簡單表示以下:json

  +-------------------------------------------+
  | Server                                    |
  | (single-threaded, event-driven etc)       |
  +-------------------------------------------+
  | Processor                                 |
  | (compiler generated)                      |
  +-------------------------------------------+
  | Protocol                                  |
  | (JSON, compact etc)                       |
  +-------------------------------------------+
  | Transport                                 |
  | (raw TCP, HTTP etc)                       |
  +-------------------------------------------+

Transport (傳輸)網絡

傳輸層提供了一個用於向網絡讀寫的簡單抽象. 經過這種方式, thrift能夠將下層的傳輸協議與thrift上層的其餘部分((例如序列化和反序列化)分離.數據結構

下面是Transport接口提供的一些方法: 函數

(1) open編碼

(2) closespa

(3) read設計

(4) writecode

(5) flushserver

除了上面的Transport接口, Thrift還使用ServerTransport接口來接受或者生成基本的transport對象. 正如名字所建議的, ServerTransport主要用在服務端爲新來的鏈接建立新的 Transport對象. 提供的方法以下:

(1) open

(2) listen

(3) accept

(4) close

絕大多數thrift支持的語言均可用的transport以下:

(1) file: 從硬盤中讀寫文件

(2) http: http網絡通訊

 

Protocol (協議)

Protocol用來定義內存中的數據結構如何使用下層的Transport來序列化和反序列化自身. 因此protocol實現用來控制編碼模式, 以及用於序列化和反序列化. protocol的一些實例包括JSON, XML, plain text, 緊湊的二進制編碼等.

下面是Protocol的接口:

writeMessageBegin(name, type, seq)
writeMessageEnd()
writeStructBegin(name)
writeStructEnd()
writeFieldBegin(name, type, id)
writeFieldEnd()
writeFieldStop()
writeMapBegin(ktype, vtype, size)
writeMapEnd()
writeListBegin(etype, size)
writeListEnd()
writeSetBegin(etype, size)
writeSetEnd()
writeBool(bool)
writeByte(byte)
writeI16(i16)
writeI32(i32)
writeI64(i64)
writeDouble(double)
writeString(string)

name, type, seq = readMessageBegin()
                  readMessageEnd()
name = readStructBegin()
       readStructEnd()
name, type, id = readFieldBegin()
                 readFieldEnd()
k, v, size = readMapBegin()
             readMapEnd()
etype, size = readListBegin()
              readListEnd()
etype, size = readSetBegin()
              readSetEnd()
bool = readBool()
byte = readByte()
i16 = readI16()
i32 = readI32()
i64 = readI64()
double = readDouble()
string = readString()

Thrift Protocols是面向字節流設計的. 這裏不須要進行顯式的分片. 例如, 咱們在序列化時, 不須要知道字符串的長度, 也不須要知道list的元素個數. 對於絕大多數thrift支持的語言都支持的Protocol(協議)有:

(1) binary: 很簡單的二進制編碼, 現將成員的長度和類型編碼成字節, 而後跟上成員的實際值

(2) 緊湊的編碼格式 (參考 https://issues.apache.org/jira/browse/THRIFT-110)

(3) json格式

 

Processor (處理單元)

一個Processor用來封裝從輸入流讀取數據和向輸出流寫入數據的能力. 輸入流和輸出流使用Protocol對象來表示. Processor的接口很簡單:

interface TProcessor {
    bool process(TProtocol in, TProtocol out) throws TException
}

服務端特定的processor實現由編譯器生成. Processor所作的是從輸入protocol中讀取數據, 而後將這些數據轉交給handler(具體處理單元, 用戶實現), 而後再將結果寫入到輸出protocol中.

 

Server

Server用來將上述特徵彙集到一塊兒:

(1) 建立一個基於Handler的Processor

(2) 建立一個transport

(3) 建立輸入和輸出協議(protocol)

基於上面的組員, 建立一個Server, 而後Server調用serve函數, 等待鏈接, 而後對請求進行處理.

參考示例 (C++):

class SharedServiceHandler : virtual public SharedServiceIf {
 public:
  SharedServiceHandler() {
    // Your initialization goes here
  }

  void getStruct(SharedStruct& _return, const int32_t key) {
    // Your implementation goes here
    printf("getStruct\n");
  }

};

int main(int argc, char **argv) {
  int port = 9090;
  shared_ptr<SharedServiceHandler> handler(new SharedServiceHandler());
  shared_ptr<TProcessor> processor(new SharedServiceProcessor(handler));
  shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
  server.serve();
  return 0;
}
相關文章
相關標籤/搜索