简单学习rpc -- thrift demos
来源:互联网 发布:企业软件收费模式 编辑:程序博客网 时间:2024/06/06 20:07
简单介绍:
- fb开源的远程服务调用(rpc)框架(序列化和rpc一站式解决)。
- 接口描述语言(IDL)创建服务,支持跨语言服务开发,透明通信(利用代码生成引擎)。
- 序列化二进制数据传输。
- 用到的数据结构全部静态化,需要事先定义,中途修改需要重新编译。
- 快速的开发socket server和client。
start thrift
官方步骤
windows:
1. 下载trift compiler for windows
2. git clone https://git-wip-us.apache.org/repos/asf/thrift.git thrift
3. 进入thrift python库的目录:thrift/lib/py
4. 安装python组件 python setup.py install
,安装成功后会在当前目录生成/build目录,发现/build/lib和/build/lib.win32-3.5两个目录下都生成了thrift包,暂时不清楚其区别(一个是通用版?一个是win32下的3.5版本?还有在/thrit/lib/py下存在一个/src目录,也包含了thrift python所需的文件,这几个的区别暂时不清楚)。
5. 编写pingpong.thrift文件
service PingPong { string ping(),}service DingDang { string ding(),}
。
6. 利用下载的thrift compiler进行编译。thrift-0.10.0.exe --out gen --gen py pingpong.thrift
,成功后会生成/gen目录,下面有所需的PingPong包和py文件。
7. 将生成的gen包拷贝到项目下。
8. 编写服务器文件server.py
#!/usr/bin/python# -*- coding:utf-8 -*-from thrift import Thriftfrom thrift.TMultiplexedProcessor import TMultiplexedProcessorfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TBinaryProtocolfrom thrift.protocol import TCompactProtocolfrom thrift.server import TServerfrom gen.pingpong import PingPong, DingDangimport socketclass PingPongServiceServer(object): def ping(self): print(socket.gethostbyname(socket.gethostname())) return 'pong'class DingDangServiceServer(object): def ding(self): print(socket.gethostbyname(socket.gethostname())) return 'dang'# commontransport = TSocket.TServerSocket('127.0.0.1', 8080) # 通信socket并设置服务端口tfactory = TTransport.TBufferedTransportFactory() # 传输工厂类pfactory = TBinaryProtocol.TBinaryProtocolFactory() # 二进制协议工厂类# pfactory = TCompactProtocol.TCompactProtocolFactory()# processorspingpong_handler = PingPongServiceServer() # 服务实现类实例pingpong_processor = PingPong.Processor(pingpong_handler)dongdang_handler = DingDangServiceServer()dingdang_processor = DingDang.Processor(dongdang_handler)# single service# server = TServer.TSimpleServer(pingpong_processor, transport, tfactory, pfactory)# multi service 多服务multi_processor = TMultiplexedProcessor()multi_processor.registerProcessor('pingpong_service', pingpong_processor)multi_processor.registerProcessor('dingdang_service', dingdang_processor)# 单线程服务器server = TServer.TSimpleServer(multi_processor, transport, tfactory, pfactory)print("Starting python server...")server.serve()print("done!")
。
9. 编写客户端文件client.py
#!/usr/bin/python# -*- coding:utf-8 -*-from thrift import Thriftfrom thrift.protocol.TMultiplexedProtocol import TMultiplexedProtocolfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TBinaryProtocolfrom thrift.protocol import TCompactProtocolfrom gen.pingpong import PingPong, DingDangdef ping_client(): try: # common tsocket = TSocket.TSocket('127.0.0.1', 8080) # 通信socket并设置请求ip和端口 transport = TTransport.TBufferedTransport(tsocket) # 传输类型 # single service protocol = TBinaryProtocol.TBinaryProtocol(transport) # 通信协议二进制协议(与服务器端保持一致) # protocol = TCompactProtocol.TCompactProtocol(transport) # multi service 多服务 pingpong_service = TMultiplexedProtocol(protocol, 'pingpong_service![这里写图片描述](http://img.blog.csdn.net/20170414232117718?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvanc2OTAxMTQ1NDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)') dingdang_service = TMultiplexedProtocol(protocol, 'dingdang_service') pingpong_client = PingPong.Client(pingpong_service) dingdang_client = DingDang.Client(dingdang_service) transport.open() # 打开socket传输并建立连接 print("The return value is : ") print(pingpong_client.ping()) print(dingdang_client.ding()) print("............") transport.close() except Thrift.TException as tx: print('%s' % tx.message)if __name__ == '__main__': ping_client()
。
10. 分别执行server.py和client.py,得到返回结果。
客户端:
The return value is : pong............
服务器:
Starting python server...192.168.1.136
最简单的demo到此结束。很快会想到两个问题(已更新)。
问题一:各行代码的简单含义?
问题二:是否同一端口(socket)能监听多个服务?(利用TMultiplexedProcessor
和TMultiplexedProtocol
)
thrift IDL
文档
参考: Thrift 使用方法
由浅入深了解Thrift(一)——Thrift介绍与用法
对照该博客的建议写了一些枚举和自定义数据结构的返回类型,但总感觉用起来很繁琐。
认为值得注意的点:
1. 指定namespace: namespace py user_service
使生成的目录在user_service模块下,可是实际生成不在项目根目录下,出现引用错误,只能添加了sys.path.append('gen')
。
是否有其他好的解决办法?
2. 枚举无序号;自定义结构体有序号;方法参数有序号。
service UserService { th_datatype.ResultString getName(1:string user_id) th_datatype.ResultInt getAge(1:string user_id)}
3.自定义结构体的成员默认optional(必须是required)。
struct ResultBool{ 1: ThriftResult result, 2: bool value,}
4.枚举默认从0开始,可以指定默认值(16位整数)。
enum ThriftResult { SUCCESS = 1000, EXCEPTION = 1001,}
5.支持list,map,set。
6. 利用inclue导入其他thrift文件,将数据类型和服务分开定义。
include "th_datatype.thrift"
th_user.thrift
/* 定义接口函数 */namespace py user_service/* 导入数据类型 */include "th_datatype.thrift"service UserService { th_datatype.ResultString getName(1:string user_id) th_datatype.ResultInt getAge(1:string user_id)}
th_datatype.thrift
/* 定义返回值类型 */namespace py datatypeconst string VERSION = "1.0.1"/* 枚举无序号 */enum ThriftResult { SUCCESS = 1000, EXCEPTION = 1001,}/* 自定义结构体有序号 */struct ResultBool{ 1: ThriftResult result, 2: bool value,}struct ResultInt { 1: ThriftResult result, 2: i32 value,}struct ResultLong { 1: ThriftResult result, 2: i64 value,}struct ResultDouble { 1: ThriftResult result, 2: double value,}struct ResultString { 1: ThriftResult result, 2: string value,}struct ResultListString { 1: ThriftResult result, 2: list<string> value,}struct ResultSetString { 1: ThriftResult result, 2: set<string> value,}struct ResultMapStrStr { 1: ThriftResult result, 2: map<string, string> value,}
test_server.py
#!/usr/bin/python# -*- coding:utf-8 -*-import syssys.path.append('gen')from thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TBinaryProtocolfrom thrift.server import TServerfrom user_service import UserServicefrom datatype.ttypes import ThriftResult, ResultInt, ResultStringimport socketclass UserServiceHandler(object): def getName(self, user_id): host = socket.gethostbyname(socket.gethostname()) print('host: %s, user_id: %s' % (host, user_id)) return ResultString(ThriftResult.SUCCESS, 'JiangW') def getAge(self, user_id): host = socket.gethostbyname(socket.gethostname()) print('host: %s, user_id: %s' % (host, user_id)) return ResultInt(ThriftResult.SUCCESS, 23)handler = UserServiceHandler()# 注册实现类processor = UserService.Processor(handler)transport = TSocket.TServerSocket('127.0.0.1', 8080)tfactory = TTransport.TBufferedTransportFactory()pfactory = TBinaryProtocol.TBinaryProtocolFactory()server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)print("Starting python server...")server.serve()print("done!")
test_client.py
#!/usr/bin/python# -*- coding:utf-8 -*-import syssys.path.append('gen')from thrift import Thriftfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TBinaryProtocolfrom user_service import UserServicedef client_execute(): try: transport = TSocket.TSocket('127.0.0.1', 8080) transport = TTransport.TBufferedTransport(transport) protocol = TBinaryProtocol.TBinaryProtocol(transport) client = UserService.Client(protocol) transport.open() res_name = client.getName('1') print("user name %s." % res_name.result) res_age = client.getAge('1') print("user age %s." % res_age.result) print("user name: %s, age %s." % (res_name.value, res_age.value)) print("............") transport.close() except Thrift.TException as tx: print('%s' % tx.message)if __name__ == '__main__': client_execute()
- 简单学习rpc -- thrift demos
- RPC-Thrift简单应用
- 简单学习rpc -- thrift 远程调用流程简单分析
- RPC thrift学习笔记
- RPC学习----Thrift快速入门和Java简单示例
- RPC学习----Thrift快速入门和Java简单示例
- thrift 简单安装以及rpc使用心得
- thrift(1)------基于thrift通信组件的简单RPC服务
- Thrift RPC
- Thrift RPC详解
- thrift rpc框架入门
- Thrift RPC框架介绍
- Thrift RPC详解
- Python RPC 之 Thrift
- RPC-02-Thrift
- Thrift RPC实战(一).初次体验Thrift
- 使用Thrift RPC编写程序
- 使用Thrift RPC编写程序
- Android面试题
- camera 参数
- Web前端复习——Javascript复习(函数+分支结构)
- App开放接口api安全性—Token签名sign的设计与实现
- java中同步synchronized的意义,如何用它解决线程不安全的问题
- 简单学习rpc -- thrift demos
- tensorflow安装
- mysql timestamp datetime区别
- kafka常用命令
- ActiveMQ使用经验
- 多道单选题提交评分
- HashMap实现原理分析
- Android点击缩略图查看大图的缩放动画
- 1080Ti+cuda+cudnn+caffe安装