Python 消息队列rabbitmq使用之发布订阅-扇形交换机fanout

1、发布端代码

# new_p.py
import pika
import sys
'''
什么是发布/订阅:
在上一个实例中,我们搭建了一个工作队列,每个任务只分发给一个工作者(worker)。
在本实例中,我们要做的跟之前完全不一样 即:分发一个消息给多个消费者(consumers)。这种模式被称为“发布/订阅”。
'''
# 发布订阅--发布者
# 建立一个链接
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
# 链接rabbitmq
channel = connection.channel()

# 在调用queue_declare方法的时候,不提供queue参数就可以创建一个随机名的队列
# result = channel.queue_declare()

# 使用交换机,这里并没有使用指定的一个队列,而是使用交换机,这里使用的交换机是扇形交换机,并且指定交换机名为logs
channel.exchange_declare(exchange='logs',exchange_type='fanout')

# 获取消息发布
message = ' '.join(sys.argv[1:]) or "info: Hello World!"
# 开始发布消息
# 值得注意的是:发布日志消息的程序看起来和之前的没有太大区别。最重要的改变就是我们把消息发送给 logs交换机 而不是 匿名交换机
# 你会注意到routing_key为空,这是因为,它的值会被扇型交换机(fanout exchange)忽略。
channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message)

print(" [x] Sent %r"%message)
# 关闭链接
connection.close()

'''
直连交换机(direct):
直连交换机(direct exchange)来代替。路由的算法很简单
交换机将会对绑定键 和路由键 进行精确匹配,从而确定消息该分发到哪个队列。

主题交换机(topic):
发送到主题交换机(topic exchange)的消息不可以携带随意什么样子的路由键(routing_key),
它的路由键必须是一个由.分隔开的词语列表。这些单词随便是什么都可以,但是最好是跟携带它们的消息有关系的词汇。
以下是几个推荐的例子:"stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit"。词语的个数可以随意,但是不要超过255字节。
* (星号) 用来表示一个单词.
# (井号) 用来表示任意数量(零个或多个)单词。

头交换机(headers):
首部交换机是忽略routing_key的一种路由方式。路由器和交换机路由的规则是通过Headers信息来交换的,这个有点像HTTP的Headers。将一个交换机声明成首部交换机,绑定一个队列的时候,定义一个Hash的数据结构,消息发送的时候,会携带一组hash数据结构的信息,当Hash的内容匹配上的时候,消息就会被写入队列。

扇型交换机(fanout):
扇型交换机(fanout exchanges)会忽略 绑定键routing_key,无论是 basic_publish or queue_bind
'''

2、消费/订阅端代码

import pika
import time

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='logs',exchange_type='fanout')


# 因为发布订阅用的是随机名队列,所以当与消费者断开连接的时候,这个队列应当被立即删除。exclusive标识符即可达到此目的。
result = channel.queue_declare(exclusive=True)

# 在之前的实例中我们都要事先知道,队列的名字,这里采用的就是默认获取
queue_name = result.method.queue

# 开始绑定:将消费者绑定到和交换机同一个频道,这样logs交换机发来的消息,消费者就可以收到了
channel.queue_bind(exchange='logs',queue=queue_name)

print(' [*] Waiting for logs. To exit press CTRL+C')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body.decode())
    time.sleep(body.decode().count('.') )
    print(" [x] Done")

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

channel.start_consuming()
# rabbitmqctl list_bindings 列出所有现存的绑定。
# 绑定的另外一种理解:
# 绑定(binding)是指交换机(exchange)和队列(queue)的关系。
# 可以简单理解为:这个队列(queue)对这个交换机(exchange)的消息感兴趣。

3、如何运行
消费端:

python new_c.py

注意:这里多运行几个消费端,可以更好的理解
发布端:

python new_p.py hello world!
python new_p.py hello rabbitmq!
python new_p.py hello python!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haeasringnar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值