基于Apache Thrift的公路涵洞数据交互实现原理
基于Apache Thrift的公路涵洞數(shù)據(jù)交互實(shí)現(xiàn)原理
Apache Thrift簡(jiǎn)介
Apache Thrift(以下簡(jiǎn)稱為“Thrift”) 是 Facebook 實(shí)現(xiàn)的一種高效的、支持多種編程語(yǔ)言的遠(yuǎn)程服務(wù)調(diào)用的框架。
目前流行的服務(wù)調(diào)用方式有很多種,例如基于 SOAP 消息格式的 Web Service,基于 JSON 消息格式的 RESTful 服務(wù)等。其中所用到的數(shù)據(jù)傳輸方式包括 XML,JSON 等,然而 XML 相對(duì)體積太大,傳輸效率低,JSON 體積較小,新穎,但還不夠完善。本文將介紹由 Facebook 開發(fā)的遠(yuǎn)程服務(wù)調(diào)用框架 Apache Thrift,它采用接口描述語(yǔ)言定義并創(chuàng)建服務(wù),支持可擴(kuò)展的跨語(yǔ)言服務(wù)開發(fā),所包含的代碼生成引擎可以在多種語(yǔ)言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等創(chuàng)建高效的、無(wú)縫的服務(wù),其傳輸數(shù)據(jù)采用二進(jìn)制格式,相對(duì) XML 和 JSON 體積更小,對(duì)于高并發(fā)、大數(shù)據(jù)量和多語(yǔ)言的環(huán)境更有優(yōu)勢(shì)。
Thrift 架構(gòu)
Thrift 包含一個(gè)完整的堆棧結(jié)構(gòu)用于構(gòu)建客戶端和服務(wù)器端。下圖描繪了 Thrift 的整體架構(gòu)。
圖 1. 架構(gòu)圖
?
?
?
如圖所示,圖中黃色部分是用戶實(shí)現(xiàn)的業(yè)務(wù)邏輯,褐色部分是根據(jù) Thrift 定義的服務(wù)接口描述文件生成的客戶端和服務(wù)器端代碼框架,紅色部分是根據(jù) Thrift 文件生成代碼實(shí)現(xiàn)數(shù)據(jù)的讀寫操作。紅色部分以下是 Thrift 的傳輸體系、協(xié)議以及底層 I/O 通信,使用 Thrift 可以很方便的定義一個(gè)服務(wù)并且選擇不同的傳輸協(xié)議和傳輸層而不用重新生成代碼。
Thrift 服務(wù)器包含用于綁定協(xié)議和傳輸層的基礎(chǔ)架構(gòu),它提供阻塞、非阻塞、單線程和多線程的模式運(yùn)行在服務(wù)器上,可以配合服務(wù)器 / 容器一起運(yùn)行。
服務(wù)端和客戶端具體的調(diào)用流程如下:
圖 2. Server 端啟動(dòng)、服務(wù)時(shí)序圖
?
該圖所示是 HelloServiceServer 啟動(dòng)的過(guò)程以及服務(wù)被客戶端調(diào)用時(shí),服務(wù)器的響應(yīng)過(guò)程。從圖中我們可以看到,程序調(diào)用了 TThreadPoolServer 的 serve 方法后,server 進(jìn)入阻塞監(jiān)聽狀態(tài),其阻塞在 TServerSocket 的 accept 方法上。當(dāng)接收到來(lái)自客戶端的消息后,服務(wù)器發(fā)起一個(gè)新線程處理這個(gè)消息請(qǐng)求,原線程再次進(jìn)入阻塞狀態(tài)。在新線程中,服務(wù)器通過(guò) TBinaryProtocol 協(xié)議讀取消息內(nèi)容,調(diào)用 HelloServiceImpl 的 helloVoid 方法,并將結(jié)果寫入 helloVoid_result 中傳回客戶端。
圖 3. Client 端調(diào)用服務(wù)時(shí)序圖
?
該圖所示是 HelloServiceClient 調(diào)用服務(wù)的過(guò)程以及接收到服務(wù)器端的返回值后處理結(jié)果的過(guò)程。從圖中我們可以看到,程序調(diào)用了 Hello.Client 的 helloVoid 方法,在 helloVoid 方法中,通過(guò) send_helloVoid 方法發(fā)送對(duì)服務(wù)的調(diào)用請(qǐng)求,通過(guò) recv_helloVoid 方法接收服務(wù)處理請(qǐng)求后返回的結(jié)果。
Thrift環(huán)境準(zhǔn)備
1下載Thrift
當(dāng)前版本為Thrift-0.10.0。
2. 編譯或下載Thrift編譯器
windows下可以直接下載已經(jīng)編譯好的編譯器Thrift-0.10.0.exe。
涵洞數(shù)據(jù)交互實(shí)例:
1.?定義Thrift文件
exception GenericError {
}
enum SlabCulvertType {
}
struct CommonResult{
}
struct SlabCulvert {
}
service EngineerService {
????CommonResult slabCulvert_add(1: Context context,2: SlabCulvertType slabCulvertType,3: SlabCulvert slabCulvert) throws (1:GenericError e)
????CommonResult slabCulvert_modify(1: Context context,2: SlabCulvertCondition slabCulvertCondition,3: SlabCulvertType slabCulvertType,4: SlabCulvert slabCulvert) throws (1:GenericError e)
????CommonResult slabCulvert_remove(1: Context context,2: SlabCulvertCondition slabCulvertCondition) throws (1:GenericError e)
????SlabCulvertResult slabCulvert_query(1: Context context,2: SlabCulvertCondition slabCulvertCondition) throws (1:GenericError e)
}
2.?使用Thrift編譯器編譯Thrift文件
thrift --gen <language> <Thrift filename>
3.?編寫服務(wù)端代碼
#!/usr/bin/env python # -*- coding:utf-8 -*-import glob import sys sys.path.append('gen-py') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])from tutorial import EngineerServicefrom thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocol from thrift.server import TServerclass EngineerServiceHandler:def __init__(self):self.log = {}def slabCulvert_add(self, context, slabCulvertType, slabCulvert):passdef slabCulvert_modify(self, context, slabCulvertCondition, slabCulvertType, slabCulvert):passdef slabCulvert_remove(self, context, slabCulvertCondition):passdef slabCulvert_query(self, context, slabCulvertCondition):passif __name__ == '__main__':handler = EngineerServiceHandler()processor = EngineerService.Processor(handler)transport = TSocket.TServerSocket(port=9090)tfactory = TTransport.TBufferedTransportFactory()pfactory = TBinaryProtocol.TBinaryProtocolFactory()server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)print('Starting the server...')server.serve()print('done.')4.?客戶端使用框架代碼調(diào)用遠(yuǎn)程服務(wù)
#!/usr/bin/env python # -*- coding:utf-8 -*-import sys import glob sys.path.append('gen-py') sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])from tutorial import EngineerService from tutorial.ttypes import InvalidOperation, slabCulvertTypefrom thrift import Thrift from thrift.transport import TSocket from thrift.transport import TTransport from thrift.protocol import TBinaryProtocoldef main():# Make sockettransport = TSocket.TSocket('localhost', 9090)# Buffering is critical. Raw sockets are very slowtransport = TTransport.TBufferedTransport(transport)# Wrap in a protocolprotocol = TBinaryProtocol.TBinaryProtocol(transport)# Create a client to use the protocol encoderclient = EngineerService.Client(protocol)# Connect! transport.open()try:context = ...slab_culvert_type = ...slab_culvert = slabCulvert(...)res = client.slabCulvert_add(context, slab_culvert_type, slab_culvert)print(res)except InvalidOperation as e:print('InvalidOperation: %r' % e)# Close! transport.close()if __name__ == '__main__':try:main()except Thrift.TException as tx:print('%s' % tx.message)參考資料:
轉(zhuǎn)載于:https://www.cnblogs.com/yaoyu126/p/6724718.html
總結(jié)
以上是生活随笔為你收集整理的基于Apache Thrift的公路涵洞数据交互实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。