专栏首页python3Python Thrift示例

Python Thrift示例

前言

Apache Thrift 是 Facebook 实现的一种高效的、支持多种编程语言的远程服务调用的框架。本文将从 Python开发人员角度简单介绍 Apache Thrift 的架构、开发和使用。

Thrift简介

Thrift network stack

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)。

Protocol

Protocol用于对数据格式抽象,在rpc调用时序列化请求和响应。
TProtocol的实现包括:TJSONProtocol,TSimpleJSONProtocol,TBinaryProtocol,TBinaryPotocolAccelerated,TCompactProtocol。

Processor

Processor对stream读写抽象,最终会调用用户编写的handler已响应对应的service。具体的Processor有compiler生成,用户需要实现service的实现类。

Server

Server创建Transport,输入、输出的Protocol,以及响应service的handler,监听到client的请求然后委托给processor处理。
TServer是基类,构造函数的参数包括:
1) processor, serverTransport
2) processor, serverTransport, transportFactory, protocolFactory
3) processor, serverTransport, inputTransportFactory, outputTransportFactory, inputProtocolFactory, outputProtocolFactory   
TServer内部实际上需要3)所列的参数,1)和2)会导致对应的参数使用默认值。
TServer的子类包括:TSimpleServer, TThreadedServer, TThreadPoolServer, TForkingServer, THttpServer, TNonblockingServer, TProcessPoolServer
TServer的serve方法用于开始服务,接收client的请求。

Code generated

constants.py: 包含声明的所有常量
ttypes.py: 声明的struct,实现了具体的序列化和反序列化
SERVICE_NAME.py: 对应service的描述文件,包含了:
    Iface: service接口定义
    Client: client的rpc调用桩

用法

Thrift的用法实际上很简单,定义好IDL,然后实现service对应的handler(方法名、参数列表与接口定义一致接口),最后就是选择各个组件。需要选择的包括:Transport(一般都是socket,只是十分需要选择buffed和framed装饰器factory),Protocol,Server。

示例

IDL文件

/*
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
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)
transport = TSocket.TServerSocket("localhost", 9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

print "Starting thrift server in python..."
server.serve()
print "done!"

client

# coding: utf-8
"""
thrift_client.py
"""

import sys
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, 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!

小结

本文只是一个简单的示例,在实际项目中,一般会基于zookeeper来注册和管理服务的thrift状态,并对server和client进一步封装,便于在项目各个模块中调用。

参考

  1. Python thrift使用示例
  2. https://thrift.apache.org/docs/concepts

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 网络通信 & 初识socket

    即Client/Server (C/S) 结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,需要安装...

    py3study
  • python部署thrift服务以及客户

    Linux环境:thrift --gen java importservice.thrift

    py3study
  • Python 发邮件

    py3study
  • 死锁的原因,和一般的解决方案

    死锁是由四个必要条件导致的,所以一般来说,只要破坏这四个必要条件中的一个条件,死锁情况就应该不会发生。

    海涛
  • 【前沿】飞入寻常百姓家:DeepCognition.ai教你轻松部署AI应用

    【导读】你是否曾为选择TensorFlow或Keras而感到纠结?又是否认深度学习编程费时费力而感到苦恼?本文带大家领略一下DeepCognition.ai,其...

    WZEARW
  • AI芯片到底是个神马 | 解读技术 | AI基础 | 算力必备

    AI技术有三大要素:算法、算力、数据。由于AI技术的应用,对各种硬件设备的算力要求大幅提高,AI芯片应运而生,目前AI芯片发展的重点是针对神经网络等...

    用户7623498
  • Hive远程模式安装

        Hadoop的安装略,JDK的安装略。安装在192.168.33.33这台机器上。

    克虏伯
  • 深度学习为什么需要工业化标准

    【导读】近日,深度学习作者Carlos E. Perez发表一篇博客,讨论了深度学习的工业化标准问题。我们知道,深度学习是当前AI领域的一个利器,其标准也不能照...

    WZEARW
  • 吴恩达回答:深度学习的泡沫何时会破?

    有人在 Quora 上问了一个匪夷所思的问题:“深度学习的泡沫何时会破?”在短短的十几个小时内,该问题就得到了 18 个回应,而且每个回应都颇有深度。下面的内容...

    钱塘数据
  • 根据变量值拆分SAS数据集

    前几天看到一个群友提的一个问题,根据数据集中的某一个变量的值将一人大数据集拆分为多个小数据集(见上图第15题),实现这一目的的方法有多种,最常见的方法应该是宏循...

    专业余码农

扫码关注云+社区

领取腾讯云代金券