python实现RabbitMQ的消息队列的示例代码


Posted in Python onNovember 08, 2018

最近在研究redis做消息队列时,顺便看了一下RabbitMQ做消息队列的实现。以下是总结的RabbitMQ中三种exchange模式的实现,分别是fanout, direct和topic。

base.py:

import pika
# 获取认证对象,参数是用户名、密码。远程连接时需要认证
credentials = pika.PlainCredentials("admin", "admin")

# BlockingConnection(): 实例化连接对象
# ConnectionParameters(): 实例化链接参数对象
connection = pika.BlockingConnection(pika.ConnectionParameters(
  "192.168.0.102", 5672, "/", credentials))

# 创建新的channel(通道)
channel = connection.channel()

fanout模式:向绑定到指定exchange的queue中发送消息,消费者从queue中取出数据,类似于广播模式、发布订阅模式。
绑定方式: 在接收端channel.queue_bind(exchange="logs", queue=queue_name)

代码:

publisher.py:

from base import channel, connection
# 声明exchange, 不声明queue
channel.exchange_declare(exchange="logs", exchange_type="fanout") # 广播
message = "hello fanout"
channel.basic_publish(
  exchange="logs",
  routing_key="",
  body=message
)
connection.close()

consumer.py:

from base import channel, connection
    
# 声明exchange
channel.exchange_declare(exchange="logs", exchange_type="fanout")

# 不指定queue名字, rabbitmq会随机分配一个名字, 消息处理完成后queue会自动删除
result = channel.queue_declare(exclusive=True) 

# 获取queue名字
queue_name = result.method.queue

# 绑定exchange和queue
channel.queue_bind(exchange="logs", queue=queue_name)


def callback(ch, method, properties, body):
  print("body:%s" % body)


channel.basic_consume(
  callback,
  queue=queue_name
)


channel.start_consuming()

direct模式:发送端绑定一个routing_key1, queue中绑定若干个routing_key2, 若key1与key2相等,或者key1在key2中,则消息就会发送到这个queue中,再由相应的消费者去queue中取数据。

publisher.py:

from base import channel, connection
channel.exchange_declare(exchange="direct_test", exchange_type="direct")

message = "hello"

channel.basic_publish(
  exchange="direct_test",
  routing_key="info", # 绑定key
  body=message
)
connection.close()

consumer01.py:

from base import channel, connection
      
      
channel.exchange_declare(exchange="direct_test", exchange_type="direct")
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue


channel.queue_bind(
  exchange="direct_test",
  queue=queue_name,
  # 绑定的key,与publisher中的相同
  routing_key="info" 
)


def callback(ch, method, properties, body):
  print("body:%s" % body)


channel.basic_consume(
  callback,
  queue=queue_name
)


channel.start_consuming()

consumer02.py:

from base import channel, connection


channel.exchange_declare(exchange="direct_test", exchange_type="direct")
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue


channel.queue_bind(
  exchange="direct_test",
  queue=queue_name,
  # 绑定的key
  routing_key="error"  
)


def callback(ch, method, properties, bosy):
  print("body:%s" % body)


channel.basic_consume(
  callback,
  queue=queue_name
)


channel.start_consuming()

consumer03.py:

from base import channel, connection
      
      
channel.exchange_declare(exchange="direct_test", exchange_type="direct")
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue


key_list = ["info", "warning"]
for key in key_list:
  channel.queue_bind(
    exchange="direct_test",
    queue=queue_name,
    # 一个queue同时绑定多个key,有一个key满足条件时就可以收到数据
    routing_key=key 
  )


def callback(ch, method, properties, body):
  print("body:%s" % body)


channel.basic_consume(
  callback,
  queue=queue_name
)


channel.start_consuming()

执行:

python producer.py
python consumer01.py
python consumer02.py
python consumer03.py

结果:

consumer01.py: body:b'hello'
consumer02.py没收到结果
consumer03.py: body:b'hello'

topic模式不是太好理解,我的理解如下:

对于发送端绑定的routing_key1,queue绑定若干个routing_key2;若routing_key1满足任意一个routing_key2,则该消息就会通过exchange发送到这个queue中,然后由接收端从queue中取出其实就是direct模式的扩展。

绑定方式:

发送端绑定:

channel.basic_publish(
    exchange="topic_logs",
    routing_key=routing_key,
    body=message
  )

接收端绑定:

channel.queue_bind(
    exchange="topic_logs",
    queue=queue_name,
    routing_key=binding_key
  )

publisher.py:

import sys
from base import channel, connection


# 声明exchange
channel.exchange_declare(exchange="topic_test", exchange_type="topic")

# 待发送消息
message = " ".join(sys.argv[1:]) or "hello topic"

# 发布消息
channel.basic_publish(
  exchange="topic_test",
  routing_key="mysql.error",  # 绑定的routing_key
  body=message
)
connection.close()

consumer01.py:

from base import channel, connection
      
      
channel.exchange_declare(exchange="topic_test", exchange_type="topic")
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue


channel.queue_bind(
  exchange="topic_test",
  queue=queue_name,
  routing_key="*.error"  # 绑定的routing_key
)


def callback(ch, method, properties, body):
  print("body:%s" % body)


channel.basic_consume(
  callback,
  queue=queue_name,
  no_ack=True
)


channel.start_consuming()

consumer02.py:

from base import channel, connection
      
      
channel.exchange_declare(exchange="topic_test", exchange_type="topic")
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue


channel.queue_bind(
  exchange="topic_test",
  queue=queue_name,
  routing_key="mysql.*"  # 绑定的routing_key
)


def callback(ch, method, properties, body):
  print("body:%s" % body)


channel.basic_consume(
  callback,
  queue=queue_name,
  no_ack=True
)


channel.start_consuming()

执行:

python publisher02.py "this is a topic test"
python consumer01.py
python consumer02.py

结果:

consumer01.py的结果: body:b'this is a topic test'
consumer02.py的结果: body:b'this is a topic test'

说明通过绑定相应的routing_key,两个消费者都收到了消息

将publisher.py的routing_key改成"mysql.info"

再此执行:

python publisher02.py "this is a topic test"
python consumer01.py
python consumer02.py

结果:

consumer01.py没收到结果
consumer02.py的结果: body:b'this is a topic test'

通过这个例子我们就能明白topic的运行方式了。

参考自: https://3water.com/article/150386.htm

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python天气预报采集器实现代码(网页爬虫)
Oct 07 Python
在Python中利用Pandas库处理大数据的简单介绍
Apr 07 Python
Python的组合模式与责任链模式编程示例
Feb 02 Python
使用py2exe在Windows下将Python程序转为exe文件
Mar 04 Python
python if not in 多条件判断代码
Sep 21 Python
Python max内置函数详细介绍
Nov 17 Python
python3基于TCP实现CS架构文件传输
Jul 28 Python
浅谈keras保存模型中的save()和save_weights()区别
May 21 Python
Python基于smtplib模块发送邮件代码实例
May 29 Python
分享PyCharm最新激活码(真永久激活方法)不用每月找安装参数或最新激活码了
Dec 27 Python
Python Django获取URL中的数据详解
Nov 01 Python
python_tkinter事件类型详情
Mar 20 Python
对Python 3.5拼接列表的新语法详解
Nov 08 #Python
Python使用random.shuffle()打乱列表顺序的方法
Nov 08 #Python
python RabbitMQ 使用详细介绍(小结)
Nov 08 #Python
如何利用Boost.Python实现Python C/C++混合编程详解
Nov 08 #Python
python训练数据时打乱训练数据与标签的两种方法小结
Nov 08 #Python
对Python random模块打乱数组顺序的实例讲解
Nov 08 #Python
Python中对数组集进行按行打乱shuffle的方法
Nov 08 #Python
You might like
玩家交还《星际争霸》原始码光盘 暴雪报以厚礼
2017/05/05 星际争霸
php专用数组排序类ArraySortUtil用法实例
2015/04/03 PHP
PHP常见加密函数用法示例【crypt与md5】
2019/01/27 PHP
PHP7移除的扩展和SAPI
2021/03/09 PHP
HTML中不支持静态Expando的元素的问题
2007/03/08 Javascript
stream.js 一个很小、完全独立的Javascript类库
2011/10/28 Javascript
使用按钮控制以何种方式打开新窗口的属性介绍
2012/12/17 Javascript
jQuery产品间断向下滚动效果核心代码
2014/05/08 Javascript
再谈Jquery Ajax方法传递到action(补充)
2014/05/12 Javascript
jquery 表格排序、实时搜索表格内容(附图)
2014/05/19 Javascript
教你如何使用PHP输出中文JSON字符串
2014/05/22 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
jquery获取复选框的值的简单实例
2016/05/26 Javascript
js复制内容到剪贴板代码,js复制代码的简单实例
2016/10/27 Javascript
js 获取html5的data属性实现方法
2017/07/28 Javascript
node.js将MongoDB数据同步到MySQL的步骤
2017/12/10 Javascript
vue-router 手势滑动触发返回功能
2018/09/30 Javascript
JavaScript剩余操作符Rest Operator详解
2019/07/20 Javascript
JS操作json对象key、value的常用方法分析
2019/10/29 Javascript
JavaScript canvas实现雨滴特效
2021/01/10 Javascript
[04:26]2014DOTA2国际邀请赛-Newbee顺利进入胜者组决赛 独家专访战神7
2014/07/19 DOTA
利用Python破解斗地主残局详解
2017/06/30 Python
Python OpenCV 使用滑动条来调整函数参数的方法
2019/07/08 Python
Django+Celery实现动态配置定时任务的方法示例
2020/05/26 Python
解决Python 写文件报错TypeError的问题
2020/10/23 Python
pycharm 使用anaconda为默认环境的操作
2021/02/05 Python
HTML5 自动聚焦(autofocus)属性使用介绍
2013/08/07 HTML / CSS
艺术系应届生的自我评价
2013/10/19 职场文书
大学军训通讯稿
2014/01/13 职场文书
市场调查策划方案
2014/06/10 职场文书
心理学专业求职信
2014/06/16 职场文书
生活小常识广播稿
2014/09/16 职场文书
四风批评与自我批评范文
2014/10/14 职场文书
惊涛骇浪观后感
2015/06/05 职场文书
matplotlib如何设置坐标轴刻度的个数及标签的方法总结
2021/06/11 Python
HttpClient实现文件上传功能
2022/08/14 Java/Android