Exchange-fanout 广播模式

一、前言

  我们看到生产者将消息投递到Queue中,实际上这在RabbitMQ中这种事情永远都不会发生。实际的情况是,生产者将消息发送到Exchange(交换器,下图中的X),由Exchange将消息路由到一个或多个Queue中(或者丢弃)。

 

  RabbitMQ中的Exchange有四种类型,不同的类型有着不同的路由策略,RabbitMQ常用的Exchange Type有fanout、direct、topic、headers这四种。Exchange是按照什么逻辑将消息路由到Queue的?RabbitMQ中通过Binding将Exchange与Queue关联起来,这样RabbitMQ就知道如何正确地将消息路由到指定的Queue了。

  • fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。
  • direct类型的Exchange路由规则也很简单,它会把消息路由到那些binding key与routing key完全匹配的Queue中。
  • topic类型中所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息
  • headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。

二、fanout广播模式

  之前的例子都基本都是1对1的消息发送和接收,即消息只能发送到指定的queue里,但有些时候你想让你的消息被所有的Queue收到,类似广播的效果,这时候就要用到exchange模式中的fanout。

  生产端: 

# -*- coding: UTF-8 -*-

import pika

# 声明一个连接
connection = pika.BlockingConnection(pika.ConnectionParameters(
    host='localhost'))

# 声明一个管道
channel = connection.channel()

# 声明一个exchange,并命名exchange 和定义它的类型
channel.exchange_declare(exchange='test-exchange',
                         exchange_type='fanout')

# 消息内容
message = 'hello,world!'

# 生成一个消息
channel.basic_publish(exchange='test-exchange',
                      routing_key='',  # 设置为空
                      body=message,
                      )
print('[x] Sent %r' % message)

# 关闭连接
connection.close()

  消费端:

# -*- coding: UTF-8 -*-

import pika

# 创建一个连接
connection = pika.BlockingConnection(pika.ConnectionParameters(
    host='localhost'))
# 创建一个管道
channel = connection.channel()

# 声明一个exchange,并命名exchange 和定义它的类型
# 和生产端一致
channel.exchange_declare(exchange='test-exchange',
                         exchange_type='fanout')

# 在这里我们要声明队列
# 虽然在生产端我们没有声明队列,是因为消息是广播的,对所有队列发送
# 在此声明的队列也不用命名,rabbitmq会随机分配名称
# 也是就是说消费端还是要从队列中获取消息内容

result = channel.queue_declare(exclusive=True)
# exclusive=True会在使用此queue的消费者断开后,自动将queue删除

# 队列名
queue_name = result.method.queue

# 绑定exchange
channel.queue_bind(exchange='test-exchange',
                   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()

  生产者产生的消息,每一个消费者都能取到。

  注: 广播模式是实时的,也就是说,在生产端产生消息的时候,消费端必须是处于监听状态的,才能从队列中获取消息,否则就收不到本次消息,哪怕再次启动。就像广播电台和收音机一样,广播电台的内容一直播放,如果收音机不打开就收听不到,即使后面打开了,先前的内容也播放完了。

   注:

exclusive=True

# 消费端只有存在的时候,队列名才会存在,并且exchange会向这个队列中
# 发送消息,一旦消费端关闭,队列queue就会被删除

  运行3个消费者,如果关闭一个,rabbitmq中的队列直接被删除了一个

 

转载于:https://www.cnblogs.com/bigberg/p/8205110.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值