1. 程式人生 > >《Thrift官方文件》Thrift 網路棧

《Thrift官方文件》Thrift 網路棧

Thrift 網路棧

下圖是一個Thrift網路棧的簡單描述

+-------------------------------------------+
| 伺服器層                                  |
| (單執行緒由訊息驅動)                        |
+-------------------------------------------+
| 處理層                                    |
| (由編譯器自動生成的)                      |
+-------------------------------------------+
| 協議層                                    |
| (JSON格式可壓縮)                          |
+-------------------------------------------+
| 傳輸層                                    |
| (TCP、HTTP協議)                           |
+-------------------------------------------+

傳輸層(Transport)

傳輸層提供了面向網路IO的一個簡單抽象。這保證了Thrift能夠將底層傳輸和系統其他功能(例如序列化和反序列化等)解耦。

以下是一些Transport介面支援的方法:

  • open
  • close
  • read
  • write
  • flush

除了上面提及的Transport介面,Thrift還提供了可用於接收和建立基本Transport物件的ServerTransport介面。正如它名字所示,ServerTransport主要用於服務端接受請求。

以下是ServerTransport介面支援的方法:

  • open
  • listen
  • accept
  • close

以下是在絕大部分Thrift支援的語言中可供使用的基礎Transport型別:

  • file: 從磁碟中檔案讀取或者寫入到檔案中
  • http: http連結

協議層(Protocol)

協議層抽象定義了記憶體中資料到傳輸格式的對映機制。換句話說,協議定義了資料如何使用底層Transport物件來編碼和解碼。因此Protocol實現中定義了編碼模式並負責序列化/反序列化。Protocol實現的例子包括JSON,XML,純文字,壓縮二進位制等等。

以下是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的Protocol是面向流設計的,因此沒有必要去顯式分幀(framing)。比如,在開始序列化之前我們可以不用關心我們傳輸的字串長度或者列表中元素的個數。在Thrift支援的大部分程式語言中可供使用的Protocol型別有:

  • binary:簡單二進位制編碼–欄位長度和型別被編碼成二進位制並緊跟在實際欄位值後面
  • json

處理層(Processor)

Processor封裝了從輸入流讀取資料和從輸出流寫資料的能力。 上一個部分描述的Protocol物件代表了輸入流和輸出流。Processor介面非常簡單。

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

Processor實現由編譯器自動生成。從原理上,Processor通過輸入Protocol從網路上讀取資料,並將資料處理代理給使用者實現的Handler,並最終通過輸出Protocol將資料寫回到網路上。

伺服器層(Server)

一個伺服器將所有上述的元件合併到一起並按照下列流程工作:

  • 建立一個Transport物件
  • 在Transport基礎上建立輸入/輸出Protocol物件
  • 在輸入/輸出Protocol基礎上建立Processor物件
  • 監聽到來的連線並移交給Processor處理