Apache Thrift
是 Facebook
实现的一种高效的、支持多种编程语言的远程服务调用的框架。
一、简介
1、Transport
Transport
是网络读写(socket http
等)的网络抽象。用于和其他thrift
组件解耦。
Transport
的接口包括:open
, close
, read
, write
, flush
, isOpen
, readAll
。
Server
端需要ServerTransport
(对监听socket
的一种抽象),用于接收客户端连接,接口包括:listen
, accept
, close
。
python
中Transport
的实现包括:TSocket
, THttpServer
, TSSLSocket
, TTwisted
, TZlibTransport
,都是对某种协议或框架的实现。还有两个装饰器,用于为已有的Transport
添加功能,TBufferedTransport
(增加缓冲)和TFramedTransport
(添加帧)。
在创建server
时,传入的时Tranport
的工厂,这些Factory
包括:
TTransportFactoryBase(没有任何修饰,直接返回),TBufferedTransportFactory(返回带缓冲的Transport)和TFramedTransportFactory(返回帧定位的Transport)。
2、Protocol
Protocol
用于对数据格式抽象,在rpc
调用时序列化请求和响应。
TProtocol
的实现包括:TJSONProtocol
,TSimpleJSONProtocol
,TBinaryProtocol
,TBinaryPotocolAccelerated
,TCompactProtocol
。
3、Processor
Processor
对stream
读写抽象,最终会调用用户编写的handler
已响应对应的service
。具体的Processor
有compiler
生成,用户需要实现service
的实现类。
4、Server
Server
创建Transport
,输入、输出的Protocol
,以及响应service
的handler
,监听到client
的请求然后委托给processor
处理。
TServer
是基类,构造函数的参数包括:
-
processor
,serverTransport
-
processor
,serverTransport
,transportFactory
,protocolFactory
-
processor
,serverTransport
,inputTransportFactory
,outputTransportFactory
,inputProtocolFactory
,outputProtocolFactory
TServer
内部实际上需要3)所列的参数,1)和2)会导致对应的参数使用默认值。
TServer
的子类包括:TSimpleServer
, TThreadedServer
, TThreadPoolServer
, TForkingServer
, THttpServer
, TNonblockingServer
, TProcessPoolServer
TServer
的serve
方法用于开始服务,接收client
的请求。
5、Code generated
constants.py
: 包含声明的所有常量ttypes.py
: 声明的struct
,实现了具体的序列化和反序列化SERVICE_NAME.py
:对应service
的描述文件,包含了:Iface
:service
接口定义Client
:client
的rpc
调用桩
二、使用示例
1、定义IDL
文件(hello.thrift
)
/* thrift接口定义文件 */
service HelloService {
string say(1:string msg)
}
在编辑好定义文件后, 运行如下命令,生成thrift
文件。可把hello
目录移到当前目录下,便于后面调用。
Thrift -r --gen py hello.thrift
Server
:
# coding: utf-8
"""
thrift_client.py
"""
import socket
import sys
sys.path.append("./gen-py")
from hello import HelloService
from hello.ttypes import *
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
class HelloServiceHandler: # 服务句柄类
def say(self, msg):
ret = "Received: " + msg
print(ret)
return ret
handler = HelloServiceHandler() # 句柄类的实例话
processor = HelloService.Processor(handler) # 定义processor
transport = TSocket.TServerSocket("localhost", 9090) # 调用Socket传输
tfactory = TTransport.TBufferedTransportFactory() # 带缓冲的TTransport工厂
pfactory = TBinaryProtocol.TBinaryProtocolFactory() # 二进制协议工厂
server = TServer.TSimpleServer(
processor,
transport,
tfactory,
pfactory) # 初始化TServer
print("Starting thrift server in python...")
server.serve()
print("done!")
Client
:
# coding: utf-8
"""
thrift_client.py
"""
import sys
sys.path.append("./gen-py")
from hello import HelloService
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
try:
transport = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = HelloService.Client(protocol)
transport.open()
print("client - say")
msg = client.say("Hello!")
print("server - " + msg)
transport.close()
except Thrift.TException as ex:
print("%s" % (ex.message))
运行结果:
$ ptyhon thrift_client.py
client - say
server - Received: Hello!
$ python thrift_server.py
Starting thrift server in python...
Received: Hello!