zerorpc是一套小巧的,灵活的,轻量级高性能rpc框架,它基于ZeroMQ和MessagePack实现,在2012年的PyCon上由dotcloud公司开源。simple tool to solve a simple problem 是zerorpc的设计初衷,整个框架的python代码只有2000行左右。
使用pip进行安装
pip install zerorpc
先编写服务端代码
import zerorpc
class HelloRPC(object):
def hello(self, name):
'''
测试rpc
'''
return "Hello, %s" % name
s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()
服务端提供了一个HelloRPC类,只写了一个方法,接下来看如何在客户端进行调用
import zerorpc
c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")
print(c.hello("RPC"))
一旦连接了服务端,就可以远程调用服务端的代码,如果你不知道服务端都提供了哪些函数可以调用,可以使用命令查看
[root]# zerorpc tcp://0.0.0.0:4242
connecting to "tcp://0.0.0.0:4242"
[HelloRPC]
hello 测试rpc
命令会返回服务端提供的所有函数,包括函数的文档,可谓是一目了然。
zerorpc还提供了心跳检测,默认断线超时30秒,断线后会抛出LostRemote。
如果在服务端的函数里遇到了异常,不会终止服务端的进程,同时,可以在客户端捕获异常,我现在在服务端制造一个随机的异常
import zerorpc
import random
class HelloRPC(object):
def hello(self, name):
'''
测试rpc
'''
if random.randint(0, 30) % 3 == 0:
0/0
return "Hello, %s" % name
s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()
有30%的概率会抛出ZeroDivisionError异常,现在多次执行客户端代码,客户端的c.hello("RPC")就有机会抛出ZeroDivisionError异常,但是服务端并没有终止,仍然可以提供服务。
客户端可以得到完完整整的异常,就可以在客户端做一些处理,服务端虽然也会报出异常信息,但是并不影响运行,我很喜欢这个特性。
这个东西可就太猛了,它类似于python的生成器,本地进程在处理大批量数据时,为了节省内存,可以考虑用生成器。远程调用时,如果需要传输的数据很多,zerorpc提供了流式响应,可以让你像使用生成器一样来调用远程方法,先看服务端
import zerorpc
import random
class HelloRPC(object):
def hello(self, name):
'''
测试rpc
'''
if random.randint(0, 30) % 3 == 0:
0/0
return "Hello, %s" % name
@zerorpc.stream
def gen(self, start, end):
for i in range(start, end):
yield i
s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()
客户端的代码:
import zerorpc
c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")
response = c.gen(1, 10)
for i in response:
print(i)
官方建议的高可用方案是将zerorpc与HAProxy结合使用,编写haproxy.cfg
listen zerorpc 0.0.0.0:5678
mode tcp
server backend_a 192.168.0.1:5678 check
server backend_b 192.168.0.2:5678 check
启动HA,haproxy -f haproxy.cfg
客户端要连接HA所在机器的5678端口,发出去的rpc请求,将被均匀的分配给后端的两台机器进行处理。
这里讨论的是python的实现版本,首先,ZeroMQ本身就很快,服务端是gevent结合ZeroMQ,gevent的协程为高性能提供了基础保障,最后,消息的序列化使用MessagePack,它和json,xml等序列化格式相比,速度快了大约20到50倍,序列化的产出减小了大约1/2。
网上关于rpc和http的讨论很多,坦率的讲,我工作中并没有用到过rpc,惭愧惭愧。
以我的理解,如果你的系统要对外提供服务,那么应当用http,提供restful的API接口,这样做的好处是对接容易,没有人会对外提供RCP服务。
RPC多用于系统内部不同模块之间的调用,我没经历过这样的项目,不清楚在哪些情形下,RPC相比于http更有优势。
QQ交流群: 211426309