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去掉字符串中空格的方法
Mar 11 Python
python获取从命令行输入数字的方法
Apr 29 Python
通过Python实现自动填写调查问卷
Sep 06 Python
详解python函数传参是传值还是传引用
Jan 16 Python
Python异常的检测和处理方法
Oct 26 Python
django中forms组件的使用与注意
Jul 08 Python
基于Python数据分析之pandas统计分析
Mar 03 Python
django配置app中的静态文件步骤
Mar 27 Python
Python项目跨域问题解决方案
Jun 22 Python
Python爬取数据并实现可视化代码解析
Aug 12 Python
在pycharm创建scrapy项目的实现步骤
Dec 01 Python
python人工智能human learn绘图可创建机器学习模型
Nov 23 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
用函数式编程技术编写优美的 JavaScript_ibm
2008/05/16 Javascript
jQuery的一些特性和用法整理小结
2010/01/13 Javascript
JavaScript高级程序设计(第3版)学习笔记5 js语句
2012/10/11 Javascript
jQuery实现移动 和 渐变特效的点击事件
2015/02/26 Javascript
js实现图片点击左右轮播
2015/07/08 Javascript
JavaScript实现动态删除列表框值的方法
2015/08/12 Javascript
js图片翻书效果代码分享
2015/08/20 Javascript
jQuery查找dom的几种方法效率详解
2017/05/17 jQuery
vue中阻止click事件冒泡,防止触发另一个事件的方法
2018/02/08 Javascript
微信小程序实现发送验证码按钮效果
2018/12/20 Javascript
ElementUI Tree 树形控件的使用并给节点添加图标
2020/02/27 Javascript
Vue双向绑定实现原理与方法详解
2020/05/07 Javascript
jQuery 实现DOM元素拖拽交换位置的实例代码
2020/07/14 jQuery
vue实践---vue不依赖外部资源实现简单多语操作
2020/09/21 Javascript
vue-router 控制路由权限的实现
2020/09/24 Javascript
Python Web框架Pylons中使用MongoDB的例子
2013/12/03 Python
Python手机号码归属地查询代码
2016/05/04 Python
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
对变量赋值的理解--Pyton中让两个值互换的实现方法
2017/11/29 Python
对python中的pop函数和append函数详解
2018/05/04 Python
Django项目使用CircleCI的方法示例
2019/07/14 Python
Python笔记之代理模式
2019/11/20 Python
python中with语句结合上下文管理器操作详解
2019/12/19 Python
使用Python实现将多表分批次从数据库导出到Excel
2020/05/15 Python
装上这 14 个插件后,PyCharm 真的是无敌的存在
2021/01/11 Python
CSS3的first-child选择器实战攻略
2016/04/28 HTML / CSS
英国时尚服饰电商:Boohoo
2017/10/12 全球购物
德国在线订购鲜花:Fleurop
2018/08/25 全球购物
Hawes & Curtis澳大利亚官网:英国经典服饰品牌
2018/10/29 全球购物
包装类的功能、种类、常用方法
2012/01/27 面试题
比较一下entity bean和session bean
2013/12/27 面试题
测绘工程系学生的自我评价
2013/11/30 职场文书
航海技术专业毕业生推荐信
2014/07/09 职场文书
ktv好的活动方案
2014/08/17 职场文书
行政经理岗位职责
2015/04/15 职场文书
小学一年级语文教学反思
2016/03/03 职场文书