python thrift demo
简介
Thrift最初由Facebook研发,主要用于各个服务之间的RPC通信,支持跨语言,常用的语言比如C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml都支持。Thrift是一个典型的CS(客户端/服务端)结构,客户端和服务端可以使用不同的语言开发。既然客户端和服务端能使用不同的语言开发,那么一定就要有一种中间语言来关联客户端和服务端的语言,这种语言就是IDL(Interface Description Language)
thrift使用流程
明确要交互的数据格式和具体的方法,定义出thrift接口描述文件(英文叫做IntefaceDescription File)
调用thrift工具,依据thrift接口文件,生成RPC代码;
你的服务器端程序引用thrift生成的RPC代码,并实现其中的Search动作的逻辑,然后启动监听,等待客户端发来请求。
客户端同样引入并调用RPC代码来与服务器端通信
thrift IDL
1. 基本类型
thrift不支持无符号类型,因为很多编程语言不存在无符号类型,比如java
bool: 布尔类型(True or False)
byte: 有符号字节
i16: 16位有符号整数
i32: 32位有符号整数
i64: 64位有符号整数
double: 64位浮点数
string: 字符串
2. 容器类型
集合中的元素可以是除了service之外的任何类型,包括exception。
list <T> : 一系列由T类型的数据组成的有序列表,元素可以重复。会被转换成C++中的vector,Java中的ArrayList,脚本语言中的数组等。
set<T>: 一系列由T类型的数据组成的无序集合,元素不可重复。会转换成C++中的set,Java中的HashSet、Python中的Set等
map<K,V>: 一个字典结构,key为K类型,value为V类型,相当于Java中的HMap
3. 结构体
就像C语言一样,thrift也支持struct类型,目的就是将一些数据聚合在一起,方便传输管理。struct的定 义形式如下:
- struct People {
- : required string name;
- : required i32 age = ;
- : optional string sex;
- }
可以看到,结构体中每一个域都有一个正整数标识符,这个标识符并不要求连续,但一旦定义,不建议再进行修改
另外,每个域前都会有required或optional的限定,前者表示是必填域,后者则表示是可选域。域是可以有默认值的,比如上例中的“age”。
如果一个域设置为optional且在构造结构体时没有给这个域赋值,那么在使用这个结构体时,就会忽略掉这个optional的域
异常(exception)
thrift支持自定义exception,规则和struct一样,如下:
- exception RequestException {
- : i32 code;
- : string reason;
- }
除了使用exception来替代struct以外,“异常”这个类型,在语法上和刚才介绍过的结构体的用法是完全一致的。但是从语义上讲,exception和struct却大相径庭。exception是在远程调用发生异常时用来抛出异常用的
服务(Service)
服务的定义,与面向对象技术中定义一个接口很类似,而这些接口其实就是纯虚函数。thrift编译工具会根据服务的定义来产生相应的方法和函数。
每个服务,都包括了若干个函数,每个函数包括了若干参数和一个返回值(返回值可以是void.
(小技巧:返回值为void的函数,你可以在函数名前加上oneway标识符,将此函数以异步模式执行,这样在调用此函数后,函数会立即返回。)
对于返回void的函数,thrift仍然会确保函数返回,这样就表示这个函数已被正确执行,且服务器端已有返回信息了。但是如果给void的函数前加上oneway,那么此函数的返回只能表示数据已经进入传输层,并不能表示服务器端已经收到并返回了数据
- service vulgar_detect{
- bool is_vulgar(:string title),
- i32 calc(: i32 num)
- }
thrift编译工具
在我们编写好thrift接口描述文件之后,thrift编译工具就要派上用场了,它的作用就是根据thrift接口描述文件来生成相应开发语言的RPC代码.
在终端下输入:
- thrift --gen ${开发语言} ${thrift接口描述文件}
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)
小结
本文只是一个简单的示例,在实际项目中,一般会基于zookeeper来注册和管理服务的thrift状态,并对server和client进一步封装,便于在项目各个模块中调用。
python thrift demo的更多相关文章
- Python Thrift 简单示例
本文基于Thrift-0.10,使用Python实现服务器端,使用Java实现客户端,演示了Thrift RPC调用示例.Java客户端提供两个字符串参数,Python服务器端计算这两个字符串的相似度 ...
- python thrift使用实例
前言 Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.本文将从 Python开发人员角度简单介绍 Apache Thrift 的架构.开发和使 ...
- python thrift 实现 单端口多服务的过程
Thrift 是一种接口描述语言和二进制通信协议.以前也没接触过,最近有个项目需要建立自动化测试,这个项目之间的微服务都是通过 Thrift 进行通信的,然后写自动化脚本之前研究了一下. 需要定义一个 ...
- python thrift 服务端与客户端使用
一.简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, ...
- python supervisor demo deployment
I did a demo about how to deploy other python apps served by a 'supervisord' daemon processor on git ...
- win7环境下,golang thrift demo代码编译不通过
用官方的教程代码:http://thrift.apache.org/tutorial/go 用网友提供的代码:Golang RPC 之 Thrift 都出现如下情况 状况1: 编辑器中就会提醒 Can ...
- RSA签名 python PHP demo 例子
python RSA+MD5签名demo: #!/usr/bin/env python2.7 #coding:utf-8 import base64 from Crypto.PublicKey imp ...
- python thrift hbase安装连接
默认已装好 hbase,我的版本是hbase-0.98.24,并运行 python 2.7.x 步骤: sudo apt-get install automake bison flex g++ git ...
- C# Apache Thrift Demo
转载至 https://headsigned.com/posts/csharp-apache-thrift-demo/ This demo application shows how to imple ...
随机推荐
- iptable实现端口转发
利用iptables的规则来实现端口转发: 第一步需要将内核参数的net.ipv4.ip_forward=1 场景一:实现本地端口转发 本地端口转发实在PREROUTING链中将端口做NAT转换: # ...
- 032-session函数
<?php $username="guest1"; if(isset($username)) { session_name($username); } echo " ...
- 105-PHP使用var_dump查看类的类型
<?php class ren{ //定义人类 } class mao{ //定义猫类 } $ren1=new ren(); //实例化人类 $mao1=new mao(); //实例化猫类 $ ...
- React 学习笔记(3) B站视频总结1
视频地址 项目基础 react-cli // 项目结构 src │ App.js # 应用根组件 │ index.js # 入口js ├─api ├─assets ├─components ├─con ...
- ELK 教程
自从ELK首次推出以来,下载量达到了数百万次,是世界上最流行的日志管理平台.相比之下,Splunk - 该领域的历史领先者 - 宣布的客户总数才15000人. 章节 ELK 介绍 ELK 安装Elas ...
- C# Stream篇(四) -- FileStream
FileStream 目录: 如何去理解FileStream? FileStream的重要性 FileStream常用构造函数(重要) 非托管参数SafeFileHandle简单介绍 FileStre ...
- POJ-3984 迷宫问题(BFS找最短路径并保存)
问题: 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, ...
- UVA - 11212 Editing a Book(IDA*算法+状态空间搜索)
题意:通过剪切粘贴操作,将n个自然段组成的文章,排列成1,2,……,n.剪贴板只有一个,问需要完成多少次剪切粘贴操作可以使文章自然段有序排列. 分析: 1.IDA*搜索:maxn是dfs的层数上限,若 ...
- filter滤镜兼容ie的rgba属性
要在一个页面中设置一个半透明的白色div.这个貌似不是难题,只需要给这个div设置如下的属性即可: background: rgba(255,255,255,0.1); 但是要兼容到ie8.这个就有点 ...
- 对于AVL树和红黑树的理解
AVL又称(严格)高度平衡的二叉搜索树,也叫二叉查找树.平衡二叉树.window对进程地址空间的管理用到了AVL树. 红黑树是非严格平衡二叉树,统计性能要好于平衡二叉树.广泛的在C++的STL中,ma ...