一:RabbitMQ实现RPC调用

客户端:

import pika
import uuid class FibonacciRpcClient(object): def __init__(self): self.credentials = pika.PlainCredentials("admin", "admin")
self.connection = pika.BlockingConnection(pika.ConnectionParameters('10.0.0.200', credentials=self.credentials))
self.channel = self.connection.channel() result = self.channel.queue_declare(queue='', exclusive=True)
self.callback_queue = result.method.queue self.channel.basic_consume(
queue=self.callback_queue,
on_message_callback=self.on_response,
auto_ack=True) def on_response(self, ch, method, props, body):
if self.corr_id == props.correlation_id:
self.response = body def call(self, n):
self.response = None
self.corr_id = str(uuid.uuid4())
self.channel.basic_publish(
exchange='',
routing_key='rpc_queue',
properties=pika.BasicProperties(
reply_to=self.callback_queue,
correlation_id=self.corr_id,
),
body=str(n))
while self.response is None:
self.connection.process_data_events()
return int(self.response) fibonacci_rpc = FibonacciRpcClient() print(" [x] Requesting fib(30)")
response = fibonacci_rpc.call(10) # 外界看上去,就像调用本地的call()函数一样
print(" [.] Got %r" % response)

服务端:

import pika

credentials = pika.PlainCredentials("admin", "admin")
connection = pika.BlockingConnection(pika.ConnectionParameters('10.0.0.200', credentials=credentials))
channel = connection.channel() channel.queue_declare(queue='rpc_queue') def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n - 1) + fib(n - 2) def on_request(ch, method, props, body):
n = int(body) print(" [.] fib(%s)" % n)
response = fib(n) ch.basic_publish(exchange='',
routing_key=props.reply_to,
properties=pika.BasicProperties(correlation_id=props.correlation_id),
body=str(response))
ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='rpc_queue', on_message_callback=on_request) print(" [x] Awaiting RPC requests")
channel.start_consuming()

二、python中的rpc框架

SimpleXMLRPCServer

python自带的SimpleXMLRPCServer,数据包大,速度慢。

使用

只需要在服务端定义一个类,类内定义需要被调用的变量及方法,

客户端通过连接服务端,然后直接调用该类即可

服务端

from xmlrpc.server import SimpleXMLRPCServer
class RPCServer(object): def __init__(self):
super(RPCServer, self).__init__()
print(self)
self.send_data = {'server:'+str(i): i for i in range(100)}
self.recv_data = None def getObj(self):
print('get data')
return self.send_data def sendObj(self, data):
print('send data')
self.recv_data = data
print(self.recv_data)
# SimpleXMLRPCServer
server = SimpleXMLRPCServer(('localhost',4242), allow_none=True)
server.register_introspection_functions()
server.register_instance(RPCServer())
server.serve_forever()

客户端

import time
from xmlrpc.client import ServerProxy # SimpleXMLRPCServer
def xmlrpc_client():
print('xmlrpc client')
c = ServerProxy('http://localhost:4242')
data = {'client:'+str(i): i for i in range(100)}
start = time.clock() # python3.8后不支持clock(),改用perf_counter()
for i in range(50):
a=c.getObj()
print(a)
for i in range(50):
c.sendObj(data)
print('xmlrpc total time %s' % (time.clock() - start)) # python3.8后不支持clock(),改用perf_counter() if __name__ == '__main__':
xmlrpc_client()

ZeroRPC实现RPC

第三方的ZeroRPC(底层使用ZeroMQ和MessagePack),速度快,响应时间短,并发高。除此外第三方的还有grpc(谷歌推出,支持跨语言)

使用

只需要在服务端定义一个类,类内定义需要被调用的变量及方法,

客户端通过连接服务端,然后直接调用该类即可

服务端

import zerorpc

class RPCServer(object):

    def __init__(self):
super(RPCServer, self).__init__()
print(self)
self.send_data = {'server:'+str(i): i for i in range(100)}
self.recv_data = None def getObj(self):
print('get data')
return self.send_data def sendObj(self, data):
print('send data')
self.recv_data = data
print(self.recv_data)
# zerorpc
s = zerorpc.Server(RPCServer())
s.bind('tcp://0.0.0.0:4243')
s.run()

客户端

import zerorpc
import time
# zerorpc
def zerorpc_client():
print('zerorpc client')
c = zerorpc.Client()
c.connect('tcp://127.0.0.1:4243')
data = {'client:'+str(i): i for i in range(100)}
start = time.clock()
for i in range(500):
a=c.getObj()
print(a)
for i in range(500):
c.sendObj(data) print('total time %s' % (time.clock() - start)) if __name__ == '__main__':
zerorpc_client()

SimpleXMLRPCServer 和 ZeroRPC比较:

利用远程调用同样的方法,执行500次,ZeroRPC耗时大幅度的小于SimpleXMLRPCServer,所以,推荐使用ZeroRPC

三种方式实现RPC调用的更多相关文章

  1. JS基础语法---创建对象---三种方式创建对象:调用系统的构造函数;自定义构造函数;字面量的方式

    创建对象三种方式: 调用系统的构造函数创建对象 自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象) 字面量的方式创建对象 第一种:调用系统的构造函数创建对象 //小苏举例子: //实例化对 ...

  2. [OpenSource]浅谈.Net和Java互相调用的三种方式

    在很多的大型系统开发中,开发工具往往不限制于同一种开发语言,而是会使用多种开发语言的混合型开发.目前Java和.Net都声称自己占85%的市场份额,不管谁对谁错,Java和.Net是目前应用开发的两个 ...

  3. 浅谈.Net和Java互相调用的三种方式

    在很多的大型系统开发中,开发工具往往不限制于同一种开发语言,而是会使用多种开发语言的混合型开发.目前Java和.Net都声称自己占85%的市场份 额,不管谁对谁错,Java和.Net是目前应用开发的两 ...

  4. Struts2方法调用的三种方式

    在Struts2中方法调用概括起来主要有三种形式 第一种方式:指定method属性 <action name="student" class="com.itmyho ...

  5. 调用awk的三种方式

    调用awk的三种方式 调用awk有三种方式,一种为Shell命令行方式,另外两种是将awk程序写入脚本文件,然后执行该脚本文件.三种方式的命令格式归纳如下: 一.在Shell命令行输入命令调用awk, ...

  6. 调用sed命令的三种方式

    调用sed命令的三种方式 调用sed有三种方式,一种为Shell命令行方式,另外两种是将sed命令写入脚本文件,然后执行该脚本文件. 三种方式的命令格式归纳如下: 一.在Shell命令行输入命令调用s ...

  7. Solidity的三种合约间的调用方式 call、delegatecall 和 callcode

    0x00 前言 Solidity(http://solidity.readthedocs.io/en/v0.4.24/) 是一种用与编写以太坊智能合约的高级语言,语法类似于 JavaScript. S ...

  8. python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

  9. Struts2方法调用的三种方式(有新的!调用方法的说明)

    在Struts2中方法调用概括起来主要有三种形式 第一种方式:指定method属性 <action name="heroAction" class="com.ABC ...

  10. java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))

    1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...

随机推荐

  1. mapreduce和yarn集群

    mapreduce : 先分再合,分而治之 分布式计算概念: 计算方式,与集中式计算相对.将应用拆分成小的部分,分配给多台计算机处理,mapreduce是分布式的计算框架. MR的特点:易于编程,良好 ...

  2. SQL数据库常用命令

    数据库操作: 创建库:create database 数据库名 删除库:drop database 数据库名 选择库:use 数据库名 Database changed 关闭安全模式:set sql_ ...

  3. 通过curl获取当前机器IPv6的外网地址

    curl -XPOST -vB -6 -g "https://10086.cn/web-Center/commonservice/getUserIp.do" -H "Re ...

  4. 使用ms17-010对win7进行渗透(445永恒之蓝)

    永恒之蓝是指2017年4月14日晚,黑客团体Shadow Brokers(影子经纪人)公布一大批网络攻击工具,其中包含"永恒之蓝"工具,"永恒之蓝"利用Wind ...

  5. .net core 序列日志Serilog

    Serilog 是一个用于 .NET 应用程序的诊断日志库.它易于设置,具有干净的 API,并且可以在所有最新的 .NET 平台上运行.尽管即使在最简单的应用程序中它也很有用,但 Serilog 对结 ...

  6. sxt_(001_003)_spring_ioc

    一.spring简介 Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架.Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可 ...

  7. es实现规格动态域生成

    1.就是把sepc的可以提取出来作为一个域(sepc是一个规格参数) 封装搜索条件(跟jdbc流程一样) @requestparam( required = false) 的作用?   不传值后台也不 ...

  8. [vsCode]Visual Studio Code环境变量不同步

    很奇怪的事情,在设置好Path环境变量后,powershell正常了, 但是vscode不正常 解决方法竟然是: 确认{在PowerShell运行正常}后,关闭{vsCode},进入{管理员模式的Po ...

  9. 赤菟V307与Matlab的串口通信

    赤菟V307与Matlab的串口通信 赤菟V307(CH32V307)是一款RISC-V内核的MCU,搭载的是沁恒自研RISC-V内核青稞V4F,最高主频144MHz,支持单精度浮点运算(FPU). ...

  10. websocket状态码

    状态码 描述 0–999 保留段, 未使用 1000 正常关闭; 无论为何目的而创建, 该链接都已成功完成任务. 1001 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开 ...