RabbitMQ实现的RPC
1.主要思路
1.生产者发布任务时,指定properties,告知消费者处理任务完毕之后,将结果存储到reply_to指定的Queue中,本次任务的id是correlation_id
2.消费者消费完消息,即处理完任务,将结果存储到reply_to指定的Queue中,同时指定correlation_id为从任务中获取的id
3.生产者先前已经订阅过reply_to指定的Queue,当消费者把结果回传到队列中时,生产者就可以取出结果,并对比correlation_id是否是自己想要的id以确认是否是自己发送的任务。
2.消费者代码
#_*_coding:utf-8_*_
import pika
import time
# 链接socket
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
channel = connection.channel() # 生成rpc queue
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) # 收到消息就调用
# ch 管道内存对象地址
# method 消息发给哪个queue
# props 返回给消费的返回参数
# body数据对象
def on_request(ch, method, props, body):
n = int(body) print(" [.] fib(%s)" % n)
# 调用斐波那契函数 传入结果
response = fib(n) ch.basic_publish(exchange='',
# 生产端随机生成的queue
routing_key=props.reply_to,
# 获取UUID唯一 字符串数值
properties=pika.BasicProperties(correlation_id = \
props.correlation_id),
# 消息返回给生产端
body=str(response))
# 确保任务完成
ch.basic_ack(delivery_tag = method.delivery_tag) # rpc_queue收到消息:调用on_request回调函数
# queue='rpc_queue'从rpc内收
channel.basic_consume(on_request, queue='rpc_queue') print(" [x] Awaiting RPC requests")
channel.start_consuming()
3.生产者代码
import pika
import uuid
import time # 斐波那契数列 前两个数相加依次排列
class FibonacciRpcClient(object):
def __init__(self):
# 链接远程
self.connection = pika.BlockingConnection(pika.ConnectionParameters(
host='localhost'))
self.channel = self.connection.channel() # 生成随机queue
#如果你想创建一个只有自己可见的队列,即不允许其它用户访问,RabbitMQ允许你将一个Queue声明成为排他性的(Exclusive Queue)。
result = self.channel.queue_declare(exclusive=True)
# 随机取queue名字,发给消费端
self.callback_queue = result.method.queue # self.on_response 回调函数:只要收到消息就调用这个函数。
# 声明收到消息后就 收queue=self.callback_queue内的消息
self.channel.basic_consume(self.on_response, no_ack=True,
queue=self.callback_queue) # 收到消息就调用
# ch 管道内存对象地址
# method 消息发给哪个queue
# body数据对象
def on_response(self, ch, method, props, body):
# 判断本机生成的ID 与 生产端发过来的ID是否相等
if self.corr_id == props.correlation_id:
# 将body值 赋值给self.response
self.response = body def call(self, n):
# 赋值变量,一个循环值
self.response = None # 随机一次唯一的字符串
self.corr_id = str(uuid.uuid4()) # routing_key='rpc_queue' 发一个消息到rpc_queue内
self.channel.basic_publish(exchange='',
routing_key='rpc_queue',
properties=pika.BasicProperties( # 执行命令之后结果返回给self.callaback_queue这个队列中
reply_to = self.callback_queue,
# 生成UUID 发送给消费端
correlation_id = self.corr_id,
),
# 发的消息,必须传入字符串,不能传数字
body=str(n))
# 没有数据就循环收
while self.response is None:
# 非阻塞版的start_consuming()
# 没有消息不阻塞
self.connection.process_data_events()
print("no msg...")
time.sleep(0.5)
return int(self.response) # 实例化
fibonacci_rpc = FibonacciRpcClient() print(" [x] Requesting fib(30)")
response = fibonacci_rpc.call(10)
print(" [.] Got %r" % response)
RabbitMQ实现的RPC的更多相关文章
- RabbitMQ中的RPC实现
1.RPC简述 RPC,Remote Procedure Call 远程过程调用.通俗讲,两段程序不在同一个内存空间,无法直接通过方法名调用,就需要通过网络通信方式调用.对于RabbitMQ,本身就是 ...
- RabbitMQ学习之RPC(6)
在第二个教程中,我们了解到如何在多个worker中使用Work Queues分发费时的任务. 但是,如果我们需要在远程运行一个函数并且等待结果该怎么办呢?这个时候,我们需要另外一个模式了.这种模式通常 ...
- rabbitmq学习(四):利用rabbitmq实现远程rpc调用
一.rabbitmq实现rpc调用的原理 ·rabbitmq实现rpc的原理是:客户端向一个队列中发送消息,并注册一个回调的队列用于接收服务端返回的消息,该消息需要声明一个叫做correaltionI ...
- 基于RabbitMQ的跨平台RPC框架
RabbitMQRpc protocobuf RabbitMQ 实现RPC https://www.cnblogs.com/LiangSW/p/6216537.html 基于RabbitMQ的RPC ...
- python项目开发:用RabbitMQ实现异步RPC
程序要求: 1. 用Rabbit MQ实现RPC 1. 可以异步地执行多条命令 2. 可以对一次性对多个机器执行命令 程序效果: --->run dir host1 host2 .... --- ...
- 8.RabbitMQ系列之RPC
1. RPC Remote Procedure Call:远程过程调用,一次远程过程调用的流程即客户端发送一个请求到服务端,服务端根据请求信息进行处理后返回响应信息,客户端收到响应信息后结束 2. C ...
- 【译】RabbitMQ:远程过程调用(RPC)
在教程二中,我们学习了如何使用工作队列在多个工作线程中分发耗时的任务.但如果我们需要去执行远程机器上的方法并且等待结果会怎么样呢?那又是另外一回事了.这种模式通常被称为远程过程调用(RPC). 本教程 ...
- (转)RabbitMQ消息队列(七):适用于云计算集群的远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,我们有可能会在接收到Message进行处理时,会把一部分计算任务分配到其他节点来完成.那么,RabbitMQ如何使用RPC呢?在本篇文章中,我们将会 ...
- RabbitMQ系列教程之六:远程过程调用(RPC)
远程过程调用(Remote Proceddure call[RPC])(本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...
随机推荐
- WebApi是轻量级的,WCF是重量级的,可以Api调用WCF,更灵活
WCF.WebAPI.WCFREST.WebService之间的区别 注明:转载 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在 ...
- 清除Pycharm设置的方法
Mac 按需运行下面的 rm 删除命令 # Configuration rm -rf ~/Library/Preferences/PyCharm* # Caches rm -rf ~/Library/ ...
- Devexpress ChartControl 柱状图简单例子
//using DevExpress.XtraEditors; //using DevExpress.XtraCharts; // Create an empty chart. ChartContro ...
- loadrunner12.5-添加检查点
1.点击缩略图资源管理器,找到需要添加检查点的页面. 2.选中需要添加检查点的页面,切换到快照tab,选择“树”型显示方式. 3.在响应窗口下,找到需要添加的检查点的内容,选中--右键--添加文本检查 ...
- dwr 框架 ,实现 ajax 的java 框架
1. 引入 dwr.jar 包 2. 配置web.xml 文件 ,拦截请求 <servlet> <servlet-name>dwr-invoker</servlet-na ...
- hdu-1130(卡特兰数+大数乘法,除法模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1130 卡特兰数:https://blog.csdn.net/qq_33266889/article/d ...
- C语言之计算字符串最后一个单词的长度,单词以空格隔开
//计算字符串最后一个单词的长度,单词以空格隔开. #include<stdio.h> #include<string.h> #include<windows.h> ...
- POJ 3621 Sightseeing Cows (bellman-Ford + 01分数规划)
题意:给出 n 个点 m 条有向边,要求选出一个环,使得这上面 点权和/边权和 最大. 析:同样转成是01分数规划的形式,F / L 要这个值最大,也就是 G(r) = F - L * r 这个值为0 ...
- cxf-rs client 调用
org.apache.cxf.jaxrs.client.WebClient get调用 @GET @Path("/echo/{input}") @Produces("te ...
- c# Clipboard.SetDataObject(bmp1) 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常
c# Clipboard.SetDataObject(bmp1) 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttri ...