ToRPC(Tornado + RPC) 是一个的基于Tornado IOLoop的异步TCP和双向通讯的RPC的Python实现。ToRPC很是轻量级,性能优秀(尤为是在PyPy环境下)。node
地址:https://github.com/yoki123/torpcpython
在Python中,消息队列、RPC框架都有不少,不少框架的完成度和稳定性都不错了,可是速度却不尽人意(真的就是慢),因而产生了造一个轮子的想法————一款能够压榨服务器资源的RPC框架。ios
对比多款框架后,发现了A fast MessagePack RPC library,它是基于Cython、Gevent、MsgPack完成的一款,它的简洁和高性能吸引了我,再使用过程当中,我试图再优化的时候,发现基本上已经达到CPU和网络I/O的瓶颈。git
由于使用Cython和gevent,后者底层也是C语言实现的,那么CPU消耗是没有的办法的时候,将MsgPack换成速度更快的marshal速度提高了10%左右,可是流量随之增长了,最后还要考虑marshal跨版本时的兼容问题(ToRPC目前也是marshal)。github
既然达到瓶颈了,试试别的框架吧,后来又找到了echo servers in many languages。 根据这个代码,Python部分的Echo servers的性能顺序是这样的:web
结论是pypy配合event-driven的tornado性能最好,它的速度和Golang(1.5)及C++ + epoll更接近。而我本身又在pypy下测试了的tornado、twisted、eventlet,仍是tornado最快。最后的抉择是使用tornado,思路是单进程、纯异步(这不就是nodejs么)。服务器
在tornado下的rpc服务器已经有msgpack-rpc-python, 而比较server_tornado.py
和server_tornado_iostream.py
以后,发现IOStream很是影响性能。并且msgpack-rpc-python
正好使用了IOStream,而且不支持双向RPC。 好吧,是时候去简化IOStream了。一开始将IOStream中的_read_buffer
和_write_buffer
从collections.deque()
换成Queue
以后,性能却更差了。 索性仍是不换了,直接撸纯event-driven,简化大量API以后,新的轮子比自带IOStream在效率上仍是有很大的提高。网络
ToRPC主要的特点是支持双向的RPC,client
能够调用server
的同时也可使用server
调用client
。 最后为了让多个client
之间相互调用而不须要开多个RPC服务器,引入了一个RPC服务注册的机制,实现了任何两个RPC client
能够经过RPC server
中转实现RPC调用,固然这样会让RPC server
的负担更重了。双向RPC的使用方法在examples文件夹中。框架
ToRPC支持在RPC、TCP应用中使用callback
方式,一样也支持返回Future
,这使得Tornado中concurrent的方式能够在ToRPC中使用。异步
from torpc import RPCClient def result_callback(f): print(f.result()) @gen.coroutine def using_gen_style(): want_to_say = 'way to explore' ret = yield rc.call('echo', want_to_say) assert ret == want_to_say print('gen_style complete') rc = RPCClient(('127.0.0.1', 5000)) rc.call('echo', 'hello world', callback=result_callback) future = rc.call('echo', 'code for fun') future.add_done_callback(result_callback) using_gen_style()
系统: CentOS 6.6 x64<br/> 处理器: Intel i5-3470 3.20GHz<br/> 内存: 8 GB 1600 MHz DDR3
到目前来看,ToRPC虽然是东拼西凑的一个轮子,可是它的性能是有目共睹的,尤为是在PyPy环境下。
msgpack-rpc-python
和mprpc
的结果能够从下方连接进入。
最后,ToRPC仍有不少不少不足的地方,若是发现问题或者有好的想法能够提issue或者提交pull Requests,examples文件夹下有使用方法。