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调用短信猫控件实现发短信功能实例
Jul 04 Python
Python中if __name__ == "__main__"详细解释
Oct 21 Python
Python中转换角度为弧度的radians()方法
May 18 Python
python实现查找excel里某一列重复数据并且剔除后打印的方法
May 26 Python
Python实现的个人所得税计算器示例
Jun 01 Python
python 对txt中每行内容进行批量替换的方法
Jul 11 Python
浅谈python写入大量文件的问题
Nov 09 Python
pygame游戏之旅 添加碰撞效果的方法
Nov 20 Python
Python 多个图同时在不同窗口显示的实现方法
Jul 07 Python
python实现身份证实名认证的方法实例
Nov 08 Python
Django def clean()函数对表单中的数据进行验证操作
Jul 09 Python
Python实现灰色关联分析与结果可视化的详细代码
Mar 25 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
Windows下PHP的任意文件执行漏洞
2006/10/09 PHP
PHP获取网站域名和地址的代码
2008/08/17 PHP
PHP与C#分别格式化文件大小的代码
2011/05/14 PHP
php获取post中的json数据的实现方法
2011/06/08 PHP
PHP删除非空目录的函数代码小结
2013/02/28 PHP
关于PHP内存溢出问题的解决方法
2013/06/25 PHP
js实现绿白相间竖向网页百叶窗动画切换效果
2015/03/02 Javascript
Bootstrap Chart组件使用教程
2016/04/28 Javascript
PHP捕捉异常中断的方法
2016/10/24 Javascript
jQuery电话号码验证实例
2017/01/05 Javascript
使用nodejs+express实现简单的文件上传功能
2017/12/27 NodeJs
JavaScript中arguments和this对象用法分析
2018/08/08 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
2018/12/05 Javascript
nodejs异步编程基础之回调函数用法分析
2018/12/26 NodeJs
node.js实现简单的压缩/解压缩功能示例
2019/11/05 Javascript
node.js +mongdb实现登录功能
2020/06/18 Javascript
Antd中单个DatePicker限定时间输入范围操作
2020/10/29 Javascript
python 将字符串转换成字典dict
2013/03/24 Python
Python如何读取MySQL数据库表数据
2017/03/11 Python
python 显示数组全部元素的方法
2018/04/19 Python
python创建学生管理系统
2019/11/22 Python
python中wheel的用法整理
2020/06/15 Python
通过代码实例了解Python异常本质
2020/09/16 Python
财务总监管理职责范文
2014/03/09 职场文书
热爱祖国演讲稿
2014/05/04 职场文书
行政监察建议书
2014/05/19 职场文书
信访工作经验交流材料
2014/05/23 职场文书
办公室文员工作自我鉴定
2014/09/19 职场文书
医学生自荐信范文
2015/03/05 职场文书
个人思想政治总结
2015/03/05 职场文书
部门2015年度工作总结
2015/04/29 职场文书
党支部考察意见范文
2015/06/02 职场文书
二年级数学教学反思
2016/02/16 职场文书
纯CSS实现hover图片pop-out弹出效果的实例代码
2021/04/16 HTML / CSS
Python帮你解决手机qq微信内存占用太多问题
2022/02/15 Python
使用python创建股票的时间序列可视化分析
2022/03/03 Python