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中的fileinput模块的简单实用示例
Jul 09 Python
Python并发之多进程的方法实例代码
Aug 15 Python
Python基础之循环语句用法示例【for、while循环】
Mar 23 Python
python实现Excel文件转换为TXT文件
Apr 28 Python
Python学习笔记之文件的读写操作实例分析
Aug 07 Python
python中调试或排错的五种方法示例
Sep 12 Python
Python常用编译器原理及特点解析
Mar 23 Python
scrapy爬虫:scrapy.FormRequest中formdata参数详解
Apr 30 Python
Python Celery异步任务队列使用方法解析
Aug 10 Python
Python 远程开关机的方法
Nov 18 Python
python3判断IP地址的方法
Mar 04 Python
python 如何获取页面所有a标签下href的值
May 06 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 将excel导入mysql
2009/11/09 PHP
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
2010/03/15 PHP
Smarty模板常见的简单应用分析
2016/11/15 PHP
基于php实现的验证码小程序
2016/12/13 PHP
laravel 解决ajax异步提交数据,并还回填充表格的问题
2019/10/15 PHP
浅谈laravel orm 中的一对多关系 hasMany
2019/10/21 PHP
jquery中:input和input的区别分析
2011/07/13 Javascript
jquery获取radio值(单选组radio)
2014/10/16 Javascript
超级简单的jquery操作表格方法
2014/12/15 Javascript
js的toLowerCase方法用法实例
2015/01/27 Javascript
Node.js重新刷新session过期时间的方法
2016/02/04 Javascript
详解js中的apply与call的用法
2016/07/30 Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
2017/03/17 Javascript
Angular 4 依赖注入学习教程之FactoryProvider的使用(四)
2017/06/04 Javascript
浅谈Postman解决token传参的问题
2018/03/31 Javascript
jQuery实现使用sort方法对json数据排序的方法
2018/04/17 jQuery
开发用到的js封装方法(20种)
2018/10/12 Javascript
js核心基础之闭包的应用实例分析
2019/05/11 Javascript
解决python线程卡死的问题
2019/02/18 Python
详解Python循环作用域与闭包
2019/03/21 Python
Python中判断子串存在的性能比较及分析总结
2019/06/23 Python
Python变量、数据类型、数据类型转换相关函数用法实例详解
2020/01/09 Python
基于python3实现倒叙字符串
2020/02/18 Python
浅谈selenium如何应对网页内容需要鼠标滚动加载的问题
2020/03/14 Python
jupyter lab的目录调整及设置默认浏览器为chrome的方法
2020/04/10 Python
OpenCV+python实现实时目标检测功能
2020/06/24 Python
Python 解析xml文件的示例
2020/09/29 Python
比利时家具购买网站:Home24
2019/01/03 全球购物
销售业务实习自我鉴定
2013/09/23 职场文书
大学生护理专业自荐信
2013/10/03 职场文书
员工三分钟演讲稿
2014/08/19 职场文书
爱国主义教育演讲稿
2014/08/26 职场文书
保密工作整改报告
2014/11/06 职场文书
湘江北去观后感
2015/06/15 职场文书
励志语录:时光飞逝,请学会珍惜所有的人和事
2020/01/16 职场文书
怎么用Python识别手势数字
2021/06/07 Python