交换机-direct
direct模式
direct
模式是交换机的另一个模式,它和fanout
比较相似,且使用更加灵活。
fanout
模式下,消费者的队列只要绑定到交换机,任何消息不加区分的全部接收。
direct
模式下,消费者的队列可以指定"关键字",只接受和"关键字"相对应的消息,其余类型消息不接收。
这类似于:双方对暗号,只有暗号一致,才接收对方发过来的消息。
direct
模式下:
- 消费者的队列在绑定交换机时,可以附加指定多个"关键字",即指定接受这些"关键词"对应的消息。
- 与此同时,生产者发布消息时,肯定要给消息附加一个"关键字"类型,这样才能让消费者的对队列选择接收。
# fanout 模式下消费者的队列绑定交换机
channel.queue_bind(exchange=exchange_name,
queue=queue_name)
# direct 模式下队列绑定队列时,附加一个"关键字",表示接收这个类型的消息;通过参数routing_key指定
channel.queue_bind(exchange=exchange_name,
queue=queue_name,
routing_key='black')
补充:
- 交换机的类型不同,绑定时的参数
routing_key
的意义不同,在fanout
模式下,不使用routing_key
; - 注意区分消息发布时的参数
routing_key
和绑定交换机时的参数routing_key
; - 当消费者需要接收多种类型的消息时,可以多次绑定这个交换机,每次绑定时提供不同的关键字
routing_key
;如使用for
循环的方式。
key_list = ['black', 'green', 'orange']
for my_key in key_list:
channel.queue_bind(exchange=exchange_name,
queue=queue_name,
routing_key=my_key)
如上图所示:在direct模式下,Q1仅接收orange类型的消息;Q2接收black和green类型的消息;
注意:Q1也可以再绑定一个black关键字,即black类型的消息会同时发给Q1和Q2;
代码
注意:新的交换机,不能与已有类型的交换机重名
生产者.py
- 连接rabbitmq
- 建交换机,指定为 direct
- 发消息,提供附加关键字 routing_key
import pika
# 第一步,连接rabbitmq
parameters = pika.ConnectionParameters(host='localhost')
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
# 第二步,建交换机,指定 direct
channel.exchange_declare(exchange='log_direct', exchange_type='direct')
# 第三步,发消息,附加关键字 routing_key
channel.basic_publish(exchange='log_direct', routing_key='green', body='Hello World!')
print(" [x] Sent 'Hello World!'")
# 主动关闭连接
connection.close()
消费者.py
- 第二步,建交换机,指定 direct
- 第三步,建队列队并绑定到交换机,绑定时提供关键字routing_key
- 其余步骤同
fanout
模式
import pika
# 第一步,连接rabbitmq
parameters = pika.ConnectionParameters(host='localhost')
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
# 第二步,建交换机,指定 direct
channel.exchange_declare(exchange='log_direct', exchange_type='direct')
# 第3步,建队列队并绑定到交换机,绑定是提供关键字routing_key
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='log_direct', queue=queue_name, routing_key='green')
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
# ch.basic_ack(delivery_tag=method.delivery_tag)
# 第4步,设置监听参数
channel.basic_consume(
queue=queue_name, on_message_callback=callback, auto_ack=True) # 默认auto_ack=False
# 第5步,开始监听
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()