Python RabbitMQ实现简单的进程间通信示例


Posted in Python onJuly 02, 2020

RabbitMQ    消息队列

PY
threading Queue
进程Queue 父进程与子进程,或同一父进程下的多个子进程进行交互
缺点:两个不同Python文件不能通过上面两个Queue进行交互

erlong
基于这个语言创建的一种中间商
win中需要先安装erlong才能使用
rabbitmq_server start

安装 Python module

pip install pika

or

easy_install pika

or
源码

rabbit      默认端口15672
查看当前时刻的队列数
rabbitmqctl.bat list_queue

exchange
在定义的时候就是有类型的,决定到底哪些queue符合条件,可以接受消息
fanout:所有bind到此exchange的queue都可以收到消息
direct:通过routingkey和exchange决定唯一的queue可以接受消息
topic: 所有符合routingkey(此时可以是一个表达式)的routingkey所bind的queue都可以接受消息
      表达式符号说明:
      # 代表一个或多个字符     * 代表任何字符

RPC
remote procedure call           双向传输,指令<-------->指令执行结果
实现方法:                        创建两个队列,一个队列收指令,一个队列发送执行结果

用rabbitmq实现简单的生产者消费者模型

1) rabbit_producer.py

# Author : Xuefeng

import pika

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()

# create the queue, the name of queue is "hello"
# durable=True can make the queue be exist, although the service have stopped before.
channel.queue_declare(queue="hello", durable=True)

# n RabbitMQ a message can never be sent directly to queue,it always need to go through
channel.basic_publish(exchange = " ",
      routing_key = "hello",
      body = "Hello world!",
      properties = pika.BasicPropreties(
       delivery_mode=2, # make the message persistence
      )
      )
print("[x] sent 'Hello world!'")
connection.close()

2) rabbit_consumer.py

# Author : Xuefeng

import pika

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()
channel.queue_declare(queue="hello", durable=True)

def callback(ch, method, properties, body):
 '''
 Handle the recieved data
 :param ch: The address of the channel
 :param method: Information about the connection
 :param properties:
 :param body:
 :return:
 '''
 print("------>", ch, method, properties )
 print("[x] Recieved %r" % body)
 # ack by ourself
 ch.basic_ack(delivery_tag = method.delivery_tag)

# follow is for consumer to auto change with the ability
channel.basic_qos(profetch_count=1)
# no_ack = True represent that the message cannot be transfor to next consumer,
# when the current consumer is stop by accident.
channel.basic_consume(callback,  # If have recieved message, enable the callback() function to handle the message.
      queue = "hello",
      no_ack = True)

print("[*] Waiting for messages. To Exit press CTRL+C")
channel.start_consuming()

用rabbitmq中的fanout模式实现广播模式

1) fanout_rabbit_publish.py

# Author : Xuefeng

import pika
import sys

# 广播模式:
# 生产者发送一条消息,所有的开通链接的消费者都可以接收到消息

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()
channel.exchange_declare(exchange="logs",
       type="fanout")
message = ' '.join(sys.argv[1:]) or "info:Hello world!"
channel.basic_publish(
 exchange="logs",
 routing_key="",
 body=message
)
print("[x] Send %r" % message)

connection.close()

2) fanout_rabbit_consumer.py

# Author : Xuefeng


import pika
import sys

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()
# exclusive 排他,唯一的 随机生成queue
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
print("Random queue name:", queue_name)

channel.queue_bind(exchange="logs",
     queue=queue_name)


def callback(ch, method, properties, body):
 '''
 Handle the recieved data
 :param ch: The address of the channel
 :param method: Information about the connection
 :param properties:
 :param body:
 :return:
 '''
 print("------>", ch, method, properties )
 print("[x] Recieved %r" % body)
 # ack by ourself
 ch.basic_ack(delivery_tag = method.delivery_tag)

# no_ack = True represent that the message cannot be transfor to next consumer,
# when the current consumer is stop by accident.
channel.basic_consume(callback,  # If have recieved message, enable the callback() function to handle the message.
      queue = "hello",
      no_ack = True)

print("[*] Waiting for messages. To Exit press CTRL+C")
channel.start_consuming()

用rabbitmq中的direct模式实现消息过滤模式

1) direct_rabbit_publisher.py

# Author : Xuefeng
import pika
import sys

# 消息过滤模式:
# 生产者发送一条消息,通过severity优先级来确定是否可以接收到消息

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()
channel.exchange_declare(exchange="direct_logs",
       type="direct")
severity = sys.argv[1] if len(sys.argv) > 1 else "info"
message = ' '.join(sys.argv[2:]) or "info:Hello world!"

channel.basic_publish(
 exchange="direct_logs",
 routing_key=severity,
 body=message
)
print("[x] Send %r:%r" % (severity, message))

connection.close()

2) direct_rabbit_consumer.py

# Author : Xuefeng

import pika
import sys

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()

channel.exchange_declare(exchange="direct_logs",
       type="direct")

# exclusive 排他,唯一的 随机生成queue
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
print("Random queue name:", queue_name)

severities = sys.argv[1:]
if not severities:
 sys.stderr.write("Usage:%s [info] [warning] [error]\n" % sys.argv[0])
 sys.exit(1)

for severity in severities:
 channel.queue_bind(exchange="direct_logs",
      queue=queue_name,
      routing_key=severity)
 


def callback(ch, method, properties, body):
 '''
 Handle the recieved data
 :param ch: The address of the channel
 :param method: Information about the connection
 :param properties:
 :param body:
 :return:
 '''
 print("------>", ch, method, properties )
 print("[x] Recieved %r" % body)
 # ack by ourself
 ch.basic_ack(delivery_tag = method.delivery_tag)

# no_ack = True represent that the message cannot be transfor to next consumer,
# when the current consumer is stop by accident.
channel.basic_consume(callback,  # If have recieved message, enable the callback() function to handle the message.
      queue = "hello",
      no_ack = True)

print("[*] Waiting for messages. To Exit press CTRL+C")
channel.start_consuming()

用rabbitmq中的topic模式实现细致消息过滤模式

1) topic_rabbit_publisher.py

# Author : Xuefeng

import pika
import sys

# 消息细致过滤模式:
# 生产者发送一条消息,通过运行脚本 *.info 等确定接收消息类型进行对应接收
connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()
channel.exchange_declare(exchange="topic_logs",
       type="topic")
binding_key = sys.argv[1] if len(sys.argv) > 1 else "info"
message = ' '.join(sys.argv[2:]) or "info:Hello world!"

channel.basic_publish(
 exchange="topic_logs",
 routing_key=binding_key,
 body=message
)
print("[x] Send %r:%r" % (binding_key, message))

connection.close()

2) topic_rabbit_consumer.py

# Author : Xuefeng

import pika
import sys

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
channel = connection.channel()

channel.exchange_declare(exchange="topic_logs",
       type="topic")

# exclusive 排他,唯一的 随机生成queue
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
print("Random queue name:", queue_name)

binding_keys = sys.argv[1:]
if not binding_keys:
 sys.stderr.write("Usage:%s [info] [warning] [error]\n" % sys.argv[0])
 sys.exit(1)

for binding_key in binding_keys:
 channel.queue_bind(exchange="topic_logs",
      queue=queue_name,
      routing_key=binding_key)


def callback(ch, method, properties, body):
 '''
 Handle the recieved data
 :param ch: The address of the channel
 :param method: Information about the connection
 :param properties:
 :param body:
 :return:
 '''
 print("------>", ch, method, properties)
 print("[x] Recieved %r" % body)
 # ack by ourself
 ch.basic_ack(delivery_tag=method.delivery_tag)


# no_ack = True represent that the message cannot be transfor to next consumer,
# when the current consumer is stop by accident.
channel.basic_consume(callback, # If have recieved message, enable the callback() function to handle the message.
      queue="hello",
      no_ack=True)

print("[*] Waiting for messages. To Exit press CTRL+C")
channel.start_consuming()

用rabbitmq实现rpc操作

1) Rpc_rabbit_client.py

# Author : Xuefeng

import pika
import time
import uuid

class FibonacciRpcClient(object):
 def __init__(self):
  self.connection = pika.BlockingConnection(pika.Connection.Parameters(
 "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):
  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.BasicPropreties(
    rely_to=self.callback_queue,
    correlation_id=self.corr_id   # 通过随机生成的ID来验证指令执行结果与指令的匹配性
   ),
   body=str(n)
  )
  while self.response is None:
   self.connection.process_data_events() # 非阻塞版的start_consume,有没有消息都继续
   print("no message...")
   time.sleep(0.5)
  return int(self.response)

fibonacci_rcp = FibonacciRpcClient()

print("[x] Requesting fib(30)")
response = fibonacci_rcp.call(30)
print("[x] Rec %r" % response)

2) Rpc_rabbit_server.py

# Author : Xuefeng

import pika
import sys

connection = pika.BlockingConnection(pika.Connection.Parameters(
 "localhost"
))
# statement a channel
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.rely_to,
  properties=pika.BasicPropreties(correlation_id=\
          props.correlation),
  body = str(body)
 )
 ch.basic_ack(delivery_tag=method.delivery_tag)

channel.basic_qos(prefetch_count=1)
channel.basic_consume(on_request, queue="rpc_queue")

print("[x] Awaiting RPC requests")
channel.start_consumeing()



channel.exchange_declare(exchange="direct_logs",
       type="direct")

# exclusive 排他,唯一的 随机生成queue
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
print("Random queue name:", queue_name)

severities = sys.argv[1:]

到此这篇关于Python RabbitMQ实现简单的进程间通信示例的文章就介绍到这了,更多相关Python RabbitMQ进程间通信内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python实现的简单hangman游戏实例
Jun 28 Python
Python读取一个目录下所有目录和文件的方法
Jul 15 Python
python下读取公私钥做加解密实例详解
Mar 29 Python
Python编程实现微信企业号文本消息推送功能示例
Aug 21 Python
浅谈python在提示符下使用open打开文件失败的原因及解决方法
Nov 30 Python
Django Rest framework之认证的实现代码
Dec 17 Python
在python中将字符串转为json对象并取值的方法
Dec 31 Python
python使用requests模块实现爬取电影天堂最新电影信息
Apr 03 Python
python opencv捕获摄像头并显示内容的实现
Jul 11 Python
Pyqt5自适应布局实例
Dec 13 Python
python的setattr函数实例用法
Dec 16 Python
python迷宫问题深度优先遍历实例
Jun 20 Python
利用scikitlearn画ROC曲线实例
Jul 02 #Python
Python使用文件操作实现一个XX信息管理系统的示例
Jul 02 #Python
keras用auc做metrics以及早停实例
Jul 02 #Python
keras 简单 lstm实例(基于one-hot编码)
Jul 02 #Python
Python装饰器结合递归原理解析
Jul 02 #Python
Python OpenCV读取中文路径图像的方法
Jul 02 #Python
keras.utils.to_categorical和one hot格式解析
Jul 02 #Python
You might like
PHP也可以?成Shell Script
2006/10/09 PHP
PHP中通过ADO调用Access数据库的方法测试不通过
2006/12/31 PHP
PHP开发不能违背的安全规则 过滤用户输入
2011/05/01 PHP
PHP连接MySQL查询结果中文显示乱码解决方法
2013/10/25 PHP
PHP实现生成模糊图片的方法示例
2017/12/21 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
laravel + vue实现的数据统计绘图(今天、7天、30天数据)
2018/07/31 PHP
animate动画示例(泪奔的小孩)及stop和delay的使用
2013/05/06 Javascript
JS实现文字向下滚动完整实例
2015/02/06 Javascript
ECMAScript6函数剩余参数(Rest Parameters)
2015/06/12 Javascript
jQuery实现监控页面所有ajax请求的方法
2015/12/10 Javascript
基于vue的短信验证码倒计时demo
2017/09/13 Javascript
Django中使用jquery的ajax进行数据交互的实例代码
2017/10/15 jQuery
Angular2使用vscode断点调试ts文件的方法
2017/12/13 Javascript
jQuery代码优化方法总结
2018/01/29 jQuery
vue判断input输入内容全是空格的方法
2018/03/02 Javascript
教你如何用node连接redis的示例代码
2018/07/12 Javascript
解决Vue.js由于延时显示了{{message}}引用界面的问题
2018/08/25 Javascript
Vue2 添加数据可视化支持的方法步骤
2019/01/02 Javascript
微信小程序错误this.setData报错及解决过程
2019/09/18 Javascript
vue3中轻松实现switch功能组件的全过程
2021/01/07 Vue.js
[39:18]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第二场 12.17
2020/12/19 DOTA
用Python一键搭建Http服务器的方法
2018/06/01 Python
Python将一个CSV文件里的数据追加到另一个CSV文件的方法
2018/07/04 Python
使用python绘制3维正态分布图的方法
2018/12/29 Python
ZWILLING双立人法国网上商店:德国刀具锅具厨具品牌
2019/08/28 全球购物
100%羊绒:NakedCashmere
2020/08/26 全球购物
商场拾金不昧表扬信
2014/01/13 职场文书
《月亮湾》教学反思
2014/04/14 职场文书
团支书竞选演讲稿
2014/04/28 职场文书
让人感觉高大上的讲话稿怎么写?
2019/07/08 职场文书
css3实现背景图片半透明内容不透明的方法示例
2021/04/13 HTML / CSS
golang中的并发和并行
2021/05/08 Golang
MySQL利用UNION连接2个查询排序失效详解
2021/11/20 MySQL
win10清理dns缓存
2022/04/19 数码科技
nginx之queue的具体使用
2022/06/28 Servers