交换机-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()
posted @ 2020-05-10 20:08  the3times  阅读(576)  评论(0)    收藏  举报