zerorpc---轻量级分布式通信框架

zerorpc

zerorpc是一套小巧的,灵活的,轻量级高性能rpc框架,它基于ZeroMQ和MessagePack实现,在2012年的PyCon上由dotcloud公司开源。simple tool to solve a simple problem 是zerorpc的设计初衷,整个框架的python代码只有2000行左右。

1. 安装方便,使用灵活

使用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。

2. 有异常怎么办

如果在服务端的函数里遇到了异常,不会终止服务端的进程,同时,可以在客户端捕获异常,我现在在服务端制造一个随机的异常

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异常,但是服务端并没有终止,仍然可以提供服务。

客户端可以得到完完整整的异常,就可以在客户端做一些处理,服务端虽然也会报出异常信息,但是并不影响运行,我很喜欢这个特性。

3. Streaming Responses

这个东西可就太猛了,它类似于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)

4. 高可用

官方建议的高可用方案是将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请求,将被均匀的分配给后端的两台机器进行处理。

5. zerorpc为什么快

这里讨论的是python的实现版本,首先,ZeroMQ本身就很快,服务端是gevent结合ZeroMQ,gevent的协程为高性能提供了基础保障,最后,消息的序列化使用MessagePack,它和json,xml等序列化格式相比,速度快了大约20到50倍,序列化的产出减小了大约1/2。

6. 什么时候用rpc

网上关于rpc和http的讨论很多,坦率的讲,我工作中并没有用到过rpc,惭愧惭愧。

以我的理解,如果你的系统要对外提供服务,那么应当用http,提供restful的API接口,这样做的好处是对接容易,没有人会对外提供RCP服务。

RPC多用于系统内部不同模块之间的调用,我没经历过这样的项目,不清楚在哪些情形下,RPC相比于http更有优势。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案