RabbitMq实现发布订阅(publish/subscribe)

场景

  • 一个生产者和多个消费者
  • 生产的消息会同时发送到所有的消费者(广播)

示意图如下:

在这里插入图片描述

在下面的例程中,生产者发送日志数据给所有的消费者,所有的消费者均接收到所有的日志消息。

生产者

代码如下:

# -*- coding: utf-8 -*-
import sys
import pika

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

# 创建Exchange
channel.exchange_declare(exchange='logs', exchange_type='fanout')

message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(exchange='logs', routing_key='', body=message)

print("[x] Sent to %r" %message)
connection.close()

详细说明:

  • 连接、通道请参考之前的博文
  • 创建Exchange。之前的例程中都使用了默认的Exchange,此处创建了一个名为logs,类型为 fanout的Exchange
    • 生产者发送的所有消息均不是直接到queue,而是到Exchange,由Exchange根据规则确定消息走向,可以追加到一个队列、多个队列或者丢弃
    • Exchange的类型决定消息转发规则,常用的有4类:direct, topic, headers 和 fanout。详细说明请参考RabbitMq入门简介
    • 此处使用fanout,它会广播所有的消息到所有的队列。使用该类型时,不必指定routing_key,因为它的值会被忽略
  • 发送消息到该Exchange。不能向未创建的Exchange发送消息。
消费者

# -*- coding: utf-8 -*-
import pika
import time

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

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

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

channel.queue_bind(exchange='logs', queue=queue_name)

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)

# 不发确认包
channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
print(' [*] Waiting for messages. To exit press CTRL+C')

channel.start_consuming()

详细说明:

  • 创建队列。之前的例程中,创建队列时都会有一个名字。命名队列对于需要在生产者和消费者之间共享该队列时是必须的。
    • 对于订阅者来说,队列的名字不重要了,因为要从所有的队列中接收消息
    • 使用空字符串会使用随机的队列名字,看起来类似于 amq.gen-Q48wnVe5JFf7BGlgeTWPWA
    • 当连接断开时,队列应该自动删除,所以使用了 exclusive=True属性
  • 绑定。绑定的是队列和Exchange。使得队列能够接收到来自Exchange的消息,所以需要把它们两者绑定起来。
    • 如果没有队列绑定到Exchange,生产者发送到该Exchange的消息会被丢弃
  • 不需要确认。消费者只关心最新的消息,不需要关心已经丢失的旧消息。
结果

可以启动任意多个消费者,当生产者启动后,所有的消费者都收到了相同的消息。

参考资料

Publish/Subscribe

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值