RabbitMQ官网教程3——发布订阅

        前面我们创建了工作队列,工作队列中每个任务只分发给一个worker。现在我们要把一个消息分发给多个消费者,这种模式就是发布订阅。为解释这种模式,我们将构建一个简单的日志系统,它包括两个程序——一个提交日志,另一个接收并打印。日志系统中每个接收程序的拷贝都会收到消息,这样可以一个将日志写入磁盘,另一个输出到屏幕。本质上讲,发布的日志消息被广播给了所有的消费者。

 

交换机

        前面的章节我们说消息发送到队列或是从队列接收消息。现在是时候介绍一下Rabbit中的消息模型了。生产者发送消息,队列存储消息,消费者接收消息。RabbitMQ中消息模型的核心是,生产者不能直接将消息发送给队列。实际上,大多数情况生产者甚至根本不知道把消息发送到哪个队列。生产者只能将消息发送到交换机。交换机很简单,一方面它从生产者接收消息,另一方面把消息推送到队列。交换机必须知道如何处理收到的消息。是该推送到一个特定的队列?还是推送到多个队列?还是丢弃?交换机类型定义了处理的规则。几种交换机类型:direct、topic、headers、fanout。现在先只看fanout。创建一个名为logs的该类型的交换机:

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

fanout类型的交换机会广播所有收到的消息给所有它知道的队列。这正是我们的日志系统需要的。

        列出服务里的交换机可以使用rabbitmqctl:

        sudo rabbitmqctl list_exchanges

        匿名交换机,前面的章节我们使用了默认交换机,由空字符串标识:

        channel.basic_publish(exchange='',routing_key='hello', body=message)

参数exchange就是交换机的名字,空字符串表示默认或匿名交换机,消息被路由到由routing_key指定名字的队列,如果它存在的话。

        现在,我们可以将消息发布到命名的交换机了:

        channel.basic_publish(exchange='logs', routing_key='',body=message)

 

临时队列

        之前我们使用的队列都是有特定名字的。给队列命名很关键,我们需要把workers指定到相同的队列。当我们想在生产者和消费者间共享队列时,给队列命名很重要。

        但是我们的日志系统不是这种情况。我们想收到所有的消息,而不是一个子集。我们只关心当前的消息而不是旧的。我们需要这样做:

        首先,当我们连接到Rabbit我们需要一个新的空队列。我们可以使用随机的名字最好让服务为我们选一个名字来创建队列,只要我们不提供queue参数给queue_declare即可:

        result = channel.queue_declare()

result.method.queue就包含一个随机的队列名。

        其次,我们断开连接,队列应该被删除,exclusive参数可以做到:

        result =channel.queue_declare(exclusive=True)

 

绑定

        我们需要告诉交换机将消息发送到队列,交换机和队列之间的关系称为绑定。

        channel.queue_bind(exchange='logs',queue=result.method.queue)

        列出绑定,可以使用sudo rabbitmqctl list_bindings


提交log:

import pika
import sys

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

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

message = ' '.join(sys.argv[1:]) or "info: Hello World!"
channel.basic_publish(exchange='logs', routing_key='', body=message)
print(" [x] Sent %r" % message)
connection.close()

        创建连接后,声明交换机,这步很必要,因为发布到一个不存在的交换机是被禁止的。

        如果还没有队列绑定到交换机,消息将被丢弃。

接收log:

import pika

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

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

result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue

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] %r" % body)

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

channel.start_consuming()


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值