RabbitMQ(四):Publish and Subscribe

本文围绕RabbitMQ的发布与订阅模式展开。介绍了Work queue与发布订阅的区别,阐述了交换机的作用、类型。给出了生产者和消费者的代码实现,包括重要参数设置。最后得出发布与订阅可让单个生产者消息被多个消费者接收,实现单条消息对应多个任务的结论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 参考链接

https://www.rabbitmq.com/tutorials/tutorial-three-python.html

2. 关键点

  • 之前提到的 Work queue只能将任务发送给单独的一个 worker,即只有一个消费者可以消费其中的一条消息;
  • work queue的方式需要指定特定的消息队列 queue 的名称,而 publish 与 subscribe 不需要;
  • 发布 publish 和订阅 subscribe 可以做到一个生产者发布的消息,可以被多个消费者拿到并执行任务;
  • exchange 指的是交换机,作用:从生产者接收消息,并推送消息到消费者,前面两篇博客里没有指定交换机,不是没有交换机,而是使用了默认的交换机;
    • exchange_type: 指定了交换机如何处理数据,将数据直接发送给指定的消息队列,还是发送给许多队列,还是直接丢掉消息数据;
    • 交换机的类型:
      • direct;
      • topic;
      • headers;
      • fanout: 将接收到的消息发送给所有的消息队列;

3. 代码实现

生产者:功能:循环10次,并打印程序消息发布时的世界时间。

重要参数:

  • exchage: 指定特定的交换机;
  • routing_key: 空值,表示不指定;-> 是因为制定了 fanout 交换机类型决定的,如果换成其他交换机类型,这个参数需要修改;
  • result  = channel.queue_declare(queue=''): 表示不指定队列名称,随机生成队列名称,使用 result.method.queue 获取随机队列名称;
  • exculsive = True: 表示消费者连接断开以后,队列信息需要被删除;-> 如果没有消费者,消息队列里面的信息将会丢失;
  • channel.queue_bind(exchange='?', queue=result.method.queue): 将消息队列和交换机绑定;
import pika
import datetime
import time

if __name__ == "__main__":

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

    channel.exchange_declare(exchange='logs_for_test', exchange_type='fanout')
    count = 0
    while count <= 10:
        message = str(datetime.datetime.now())
        time.sleep(1)
        # 生产者将不会指定队列,所以routing_key置空
        channel.basic_publish(exchange='logs_for_test', routing_key='', body=message)
        print("[x] sent %r"%message)
        count += 1

    connection.close()

消费者:功能:读取消息

import pika

def callback(ch, method, properties, body):
    print("---> :{}".format(body))

if __name__ == "__main__":

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

    # 声明交换机名称及其类型
    channel.exchange_declare(exchange='logs_for_test', exchange_type='fanout')
    # 声明队列名称,这里置空指的是随机生成的,不代表队列名称为空,exclusive是系统会自动给队列起一个随机名字
    result = channel.queue_declare(queue='', exclusive=True)
    queue_name = result.method.queue

    # 将队列与交换机绑定,队列名需要作为传入参数
    channel.queue_bind(exchange='logs_for_test', queue=queue_name)
    print('[*] waiting for logs, want exit -> ctrl + C')

    channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
    channel.start_consuming()

4. 实现结果

生产者:

消费者1:

消费者2:

在 RabbitMQ 管理管理界面可以看到如下交换机和消息队列的绑定信息:

5. 结论

发布与订阅的方式可以实现单个生产者发布消息,多个消费者同时接受消息,并且可以实现单条消息给多个任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值