介面協議工具thrift1快速入門
簡介
Thrift是一種介面描述語言和二進位制通訊協議,它被用來定義和建立跨語言的服務。它被當作遠端過程呼叫(RPC)框架來使用,是由Facebook為“大規模跨語言服務開發”而開發的。它通過一個程式碼生成引擎聯合了一個軟體棧,來建立不同程度的、無縫的跨平臺高效服務,可以使用C#、C++(基於POSIX相容系統)、Cappuccino、Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。雖然它以前是由Facebook開發的,但它現在是Apache軟體基金會的開源專案了。該實現被描述在2007年4月的一篇由Facebook發表的技術論文中,該論文現由Apache掌管。
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的實現使用了IO/">NIO通道)。TFramedTransport必須跟這個伺服器配套使用。
- TSimpleServer – 單執行緒伺服器,它使用標準的阻塞I/O。測試時很有用。
- TThreadPoolServer – 多執行緒伺服器,它使用標準的阻塞I/O。
Thrift一些已經明確的優點包括:
- 跟一些替代選擇,比如SOAP相比,跨語言序列化的代價更低,因為它使用二進位制格式。
- 它有一個又瘦又幹淨的庫,沒有編碼框架,沒有XML配置檔案。
- 繫結感覺很自然。例如,Java使用java.util.ArrayList<String>;C++使用std::vector<std::string>。
- 應用層通訊格式與序列化層通訊格式是完全分離的。它們都可以獨立修改。
- 預定義的序列化格式包括:二進位制格式、對HTTP友好的格式,以及緊湊的二進位制格式。
- 兼作跨語言檔案序列化。
- 協議使用軟版本號機制軟體版本管理。Thrift不要求一箇中心化的和顯式的版本號機制,例如主版本號/次版本號。鬆耦合的團隊可以輕鬆地控制RPC呼叫的演進。
- 沒有構建依賴也不含非標準化的軟體。不存在不相容的軟體許可證混用的情況。

image.png
安裝
以ubuntu 為例
# apt install thrift-compiler # pip3 install thrift
快速入門
定義介面文件
service Example { string ping(), void say(1:string msg) }
伺服器端 server.py
from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.server import TServer from pygen.example import Example class ExampleHandler: def __init__(self): self.log = {} def ping(self): return "pong" def say(self, msg): print(msg) handler = ExampleHandler() processor = Example.Processor(handler) transport = TSocket.TServerSocket(port=30303) tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) print("Starting python server...") server.serve() print("done!")
客戶端 client.py
from thrift import Thrift from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from pygen.example import Example try: transport = TSocket.TSocket('localhost', 30303) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) client = Example.Client(protocol) transport.open() print(client.ping()) client.say('Hello from Python!') transport.close() except Thrift.TException as tx: print(tx.message)
執行:
$ thrift -out pygen/ --gen py example.thrift $ python3 server.py Starting python server... Hello from Python! $ python3 client.py pong
參考資料
- 討論qq群144081101 591302926 567351477 釘釘免費群21745728
- ofollow,noindex">本文最新版本地址
- 本文涉及的python測試開發庫 謝謝點贊!
- 本文相關海量書籍下載