发布订阅模式,一条消息可被多个接收者接收。注意在上一篇的tasks模式中,虽然有多个接收者,但每条消息还是只被一个接收者接收的。
发送者
#!/usr/bin/env python
import pika
import sys
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
# 指定了exchange的type
channel.exchange_declare(exchange='logs',
exchange_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()
接收者
#!/usr/bin/env python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='logs',
exchange_type='fanout')
# 下面的队列声明语句,比上一篇的少了queue选项,多了exclusive选项。
# 没有queue选项,指明没有为创建的队列命名,由服务器创建一个现在还没有出现的随机名称。
# exclusive选项,指明接收者关闭之后,创建的这条队列页随之关闭
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()
Exchanges
交换区(我的叫法,有可能不准),发送者发送的消息并没有直接发给队列,而是发给了交换区。交换区负责将消息发送到队列中。注意不同类型的交换区发送给队列的模式不同,有的发给所有在交换区注册的队列,有的只发送给一条队列,有的将消息抛弃。
交换区的类型有direct, topic, headers, fanout。subcribe模式运行在fanout下,该类型下,交换区将消息发送给所有的队列。
Bindings
交换区和队列的关系称之为绑定,channel.queue_bind方法将交换区和队列绑定在一起。
另外两个命令
sudo rabbitmqctl list_exchanges
sudo rabbitmqctl list_bindings
来源:oschina
链接:https://my.oschina.net/u/4293665/blog/4061773