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中使用cookielib和urllib2配合PyQuery抓取网页信息
Apr 25 Python
Django中传递参数到URLconf的视图函数中的方法
Jul 18 Python
Python实现matplotlib显示中文的方法详解
Feb 06 Python
python字典改变value值方法总结
Jun 21 Python
python图片二值化提高识别率代码实例
Aug 24 Python
Python容器使用的5个技巧和2个误区总结
Sep 26 Python
python 实现turtle画图并导出图片格式的文件
Dec 07 Python
python和node.js生成当前时间戳的示例
Sep 29 Python
python实现PolynomialFeatures多项式的方法
Jan 06 Python
基于tensorflow __init__、build 和call的使用小结
Feb 26 Python
Django开发RESTful API实现增删改查(入门级)
May 10 Python
利用Python判断你的密码难度等级
Jun 02 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
关于Appserv无法打开localhost问题的解决方法
2009/10/16 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
Zend Framework教程之Zend_Layout布局助手详解
2016/03/04 PHP
PHP抓取淘宝商品的用户晒单评论+图片+搜索商品列表实例
2016/04/14 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
2017/07/19 PHP
php设计模式之装饰模式应用案例详解
2019/06/17 PHP
解决laravel查询构造器中的别名问题
2019/10/17 PHP
如何将JS的变量值传递给ASP变量
2012/12/10 Javascript
jquery 根据name名获取元素的value值
2015/02/27 Javascript
Extjs 点击复选框在表格中增加相关信息行
2016/07/12 Javascript
原生JS实现图片轮播切换效果
2016/12/15 Javascript
Node.js实现文件上传的示例
2017/06/28 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
javascript/jquery实现点击触发事件的方法分析
2019/11/11 jQuery
javascript实现简易的计算器
2020/01/17 Javascript
Python中尝试多线程编程的一个简明例子
2015/04/07 Python
Python3读取UTF-8文件及统计文件行数的方法
2015/05/22 Python
编写Python脚本把sqlAlchemy对象转换成dict的教程
2015/05/29 Python
Python开发的HTTP库requests详解
2017/08/29 Python
Python实现压缩和解压缩ZIP文件的方法分析
2017/09/28 Python
python 实现矩阵上下/左右翻转,转置的示例
2019/01/23 Python
浅析python redis的连接及相关操作
2019/11/07 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
详解如何获取localStorage最大存储大小的方法
2020/05/21 HTML / CSS
amazeui树节点自动展开折叠面板并选中第一个树节点的实现
2020/08/24 HTML / CSS
自我评价范文分享
2014/01/04 职场文书
中学生校园广播稿
2014/01/16 职场文书
幼儿园教研活动方案
2014/01/19 职场文书
《蜗牛》教学反思
2014/02/18 职场文书
大学生学习2014年全国两会心得体会
2014/03/12 职场文书
教师党员一句话承诺
2014/03/28 职场文书
服务理念口号
2014/06/11 职场文书
大学生联谊活动策划书(光棍节)
2014/10/10 职场文书
写给老婆的保证书
2015/02/27 职场文书
PostGIS的安装与入门使用指南
2022/01/18 PostgreSQL
Redis批量生成数据的实现
2022/06/05 Redis