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