RabbitMQ RPC模型

RPC(remote procedure call)模型说通俗一点就是客户端发一个请求给远程服务端,让它去执行,然后服务端端再把执行的结果再返回给客户端。

1、服务端

import pika

#创建socket实例,声明管道,声明queue
connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost"))
channel = connection.channel()
channel.queue_declare(queue="rpc_queue") def fib(n):
"""
斐波那契数列
:param n:
:return:
"""
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): # props 是客户端发过来的消息
n = int(body)
print("fib(%s)" % n)
response = fib(n)
# 发布消息
ch.basic_publish(exchange="",
routing_key=props.reply_to, # props.reply_to从客户端取出双方约定好存放返回结果的queue
properties=pika.BasicProperties # 定义一些基本属性
(correlation_id=props.correlation_id), # props.correlation_id 从客户端取出当前请求的ID返回给客户端做验证
body=str(response))
ch.basic_ack(delivery_tag=method.delivery_tag) # 手动确认消息被消费 channel.basic_qos(prefetch_count=1) # 每次最多处理一个客户端发过来的消息
# 消费消息
channel.basic_consume(on_request, # 回调函数
queue="rpc_queue") print("Awaiting RPC requests")
channel.start_consuming()

  

2、客户端

import pika
import uuid
import time class FibonacciRpcClient(object):
"""
斐波那契数列rpc客户端
""" def __init__(self):
"""
定义好创建socket实例、声明管道、声明随机产生的唯一queue、消费信息的静态变量
"""
self.connection = pika.BlockingConnection(pika.ConnectionParameters
(host="localhost"))
self.channel = self.connection.channel()
result = self.channel.queue_declare(exclusive=True)
self.callback_queue = result.method.queue
self.channel.basic_consume(self.on_response, no_ack=True,
queue=self.callback_queue) def on_response(self, ch, method, props, body):
print("---->", method, props)
# 当服务端返回的id跟当初请求的id一致时,再去读取服务端发送的信息保持数据的一致性
if self.corr_id == props.correlation_id: # 当服务端返回的id跟当初请求的id一致时,保持数据的一致性
self.response = body def call(self,n):
self.response = None
self.corr_id = str(uuid.uuid4())
self.channel.publish(exchange="",
routing_key="rpc_queue", # 双方的request所用的queue
properties=pika.BasicProperties( # 定义基本属性
reply_to=self.callback_queue, # 定义客户端服务端双方response的所用的Q
correlation_id=self.corr_id), # 定义这次request的唯一ID
body=str(n))
while self.response is None:
self.connection.process_data_events() # 非 阻塞版的start_consumer()
print("no msg....")
time.sleep(0.5)
return int(self.response) if __name__ == "__main__":
fibonacci_rpc = FibonacciRpcClient()
print("Requesting fib(8)")
response = fibonacci_rpc.call(8)
print("Got %r" % response)

3、输出

服务端:

 Awaiting RPC requests
fib(8)

  

客户端:

Requesting fib(8)
no msg....
----> <Basic.Deliver(['consumer_tag=ctag1.cf2e7983c7d840db8c68f4571472c18d', 'delivery_tag=1', 'exchange=', 'redelivered=False', 'routing_key=amq.gen-ezXgs0tRO5SldZeRH97VPw'])> <BasicProperties(['correlation_id=601e860d-c93d-4c94-959a-3a39be177f7c'])>
no msg....
Got 21

  

【python】-- RabbitMQ RPC模型的更多相关文章

  1. Python RabbitMQ RPC实现

    远程调用方法:R(remote)  P(procedure)  C(call) 为了说明如何使用RPC服务,我们将创建一个简单的客户端类. 它将公开一个名为call的方法,它发送一个RPC请求和块,直 ...

  2. Python之路-python(rabbitmq、redis)

    一.RabbitMQ队列 安装python rabbitMQ module pip install pika or easy_install pika or 源码 https://pypi.pytho ...

  3. python RabbitMQ队列/redis

    RabbitMQ队列 rabbitMQ是消息队列:想想之前的我们学过队列queue:threading queue(线程queue,多个线程之间进行数据交互).进程queue(父进程与子进程进行交互或 ...

  4. 认识RabbitMQ交换机模型

    前言 RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读<Rabbi ...

  5. Spring - 几种RPC模型的使用与比较

    Spring中,用JMS搞RPC时会用到: org.springframework.jms.remoting.JmsInvokerServiceExporter org.springframework ...

  6. python RabbitMQ队列使用(入门篇)

    ---恢复内容开始--- python RabbitMQ队列使用 关于python的queue介绍 关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种que ...

  7. Python RabbitMQ消息队列

    python内的队列queue 线程 queue:不同线程交互,不能夸进程 进程 queue:只能用于父进程与子进程,或者同一父进程下的多个子进程,进行交互 注:不同的两个独立进程是不能交互的.   ...

  8. python调用rpc实现分布式系统

    rpc 一般俗称,远程过程调用,把本地的函数,放到远端去调用. 通常我们调用一个方法,譬如: sumadd(10, 20),sumadd方法的具体实现要么是用户自己定义,要么存在于该语言的库函数中,也 ...

  9. python RabbitMQ队列使用

    python RabbitMQ队列使用 关于python的queue介绍 关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种queue都是只能在同一个进程下 ...

随机推荐

  1. Java之JDBC学习

    (一),MySql数据库 1,MySql数据库的数据类型定义 2,完整性约束: 3,索引: 作用:唯一作用就是加快对表查询速度,索引通过快速路径方法访问来快速定位数据,从而减少磁盘的II/O; 缺点: ...

  2. 完全分布式安装hadoop

    以三个节点为例的服务器集群来安装和配置hadoop 以下是各服务器ip地址和对应所做的节点 192.168.61.128 master 192.168.61.129 slave1 192.168.61 ...

  3. 修改MySQL数据库存储位置datadir

    2017-04-14 1.找到mysql安装目录,默认是C:/ProgramData/MySQL/MySQL Server 5.1,找到my.ini.如果这个文件没有,自己建一个my.ini. 2.假 ...

  4. AJAX2.0

    Ajax2.0 早期的ajax技术不支持异步文件上传 在后面更新了ajax2.0版本  支持文件上传了 但需要借助一个对象----FormData对象 Ajax2.0大体的步骤跟以前是一样的  但也是 ...

  5. Nginx include和Nginx指令的使用

    Nginx include和Nginx指令的使用 1.nginx include 主配置文件nginx.conf中指定包含其他扩展配置文件,从而简化nginx主配置文件,实现多个站点功能 [root@ ...

  6. 2. Spring Boot返回json数据【从零开始学Spring Boot】

    在做如下操作之前,我们对之前的Hello进行简单的修改,我们新建一个包com.kfit.test.web然后新建一个类HelloControoler,然后修改App.Java类,主要是的这个类就是一个 ...

  7. Win7提示1970-01-01 000000 is not a valid data怎么办.

    1 单击屏幕右下角的时间按钮   2 选个更改日期和时间,更改日历设置   3 把短日期改成"yyyy-m-d"   4 确定即可.发现日期的表示形式变了.

  8. Android无数据线调试方法

    平时在Android设备上调试程序.通常是将Android设备用数据线和PC机相连. 可是,在没有数据线的情况下也能够: 1.将PC机和Android设备连到同一网段. 2.获取Android设备的I ...

  9. flask和pymongo的完美搭配

    1.如何进行mongo数据库的链接 import pymongo client = pymongo.MongoClient(host='192.168.*.*', port=27017,) db_au ...

  10. htmlspecialchars_decode

    htmlspecialchars_decode   htmlspecialchars_decode - 将特殊的 HTML 实体转换回普通字符 htmlspecialchars - 将特殊字符转换为 ...