RabbitMQ 中 exchange、route、queue 的关系以及发布订阅模式

RabbitMQ 中 exchange、route、queue 的关系

从AMQP协议可以看出,MessageQueue、Exchange 和 Binding 构成了 AMQP 协议的核心,下面从应用使用的角度全面的介绍如何利用 Rabbit MQ 构建消息队列以及使用过程中的注意事项。

在这里插入图片描述

  1. 声明 MessageQueue

    在RabbitMQ 中,无论是生产者发送消息还是消费这接受消息,都首先需要声明一个 MessageQueue。这就存在一个问题:这个消息队列是生产者声明还是消费这声明?解决这个问题之前需要先明确下面两点:

    • 消费者是无法订阅或者获取不存在的 MessageQueue 中消息
    • 消息被 Exchange 接受以后,如果没有匹配的Queue,则会被丢弃。

    明白上述两点后,就容易理解如果是消费者去声明 Queue,就可能会出现声明 Queue 之前生产者发送的消息被丢弃的隐患。如果应用能够通过消息重发的机制允许消息丢失,则使用次方案没有问题。但如果不允许消息丢弃,这就需要无论是生产者还是消费者,在发送或者接受消息前都需要去尝试建立消息队列。这里还有一点需要明确:如果客户端尝试建立一个已经存在的消息队列,RabbitMQ 不会做任何事情,并返回客户端建立成功。

​ 如果一个消费者在一个信道中在监听某个队列的消息,RabbitMQ 是不允许该消费者在同一个 channel 去声明其他队列的。

RabbitMQ 中可以通过 queue.declare 命令声明一个队列,可以设置该队列以下属性:

  • Exclusive: 排他队列,如果体格队列被声明为排他队列,该队列仅对首次声明它的链接可见,并在链接断开时自动删除。这里需要注意三点:
    • 排他队列是基于链接可见的,同一链接的不同信道是可以同时访问同一个链接创建的排他队列
    • ”首次“,如果一个链接已经声明了一个排他队列,其他链接是不允许建立同名的排队列的,这个与普通队列不同
    • 即使该队列是持久化的,一旦链接关闭或者客户端推出,该队列都会被自动删除的,这种队列适用只限于一个客户端发送读取消息的应用场景
  • Auto-delete: 自动创建,如果该队列没有任何订阅的消费者,该队列会被自动删除。这种队列适用于临时队列。
  • Durable:持久化,这个后面在讲
  • 其他选项:例如用户仅仅想查询某一个队列是否已存在,如果存在不想建立该队列,仍然可以调用 queue.declare,只不过需要讲参数 passive 设为 true,传给 queue.declare,如果该队列已存在则会返回 true;如果不存在,则会返回 error,但不会创建新的队列
  1. 生产者发送的消息

    ​ 在 AMQP 模型中,Exchange 是接受生产者消息并将消息路由到消息队列的关键组件。ExchangeType 和Binding 决定了消息的路由规则。所以生产者想要发送消息首先必须声明一个 Exchange 和该 Exchange 对应的 Binding。可以通过 ExchangeDeclare 和 BindingDeclare 完成。在 RabbitMQ 中,声明一个 Exchange 需要三个参数:ExchangeName、ExchangeType 和 Durable。ExchangeName 是该 Exchange 的名字,该属性在创建 Binding 和生产者通过 publish 推送消息是需要指定。ExchangeType 是指定 Exchange 的类型,在 RabbitMQ 中有三种类型的Exchange:direct ,fanout和topic

    exchange的广播类型(交换类型)exchange_type:

    • fanout: 所有bind到此exchange的queue都可以接收消息,广播模式
    • direct: 通过routing_key决定此exchange的那些匹配的queue可以接收消息,组播模式
    • topic:所有匹配routing_key的queue可以接收消息,此时type可以是一个表达式
    • headers: 通过headers 来决定把消息发给哪些queue,比较少用。

    注意⚠️:

    1. 发布者在发布时,如果订阅者是在之后才订阅的,肯定是看不到之前的广播或组播的。广播或组播是实时的,就像现实中的广播和听众一样。

    2.如果将消息发送到一个没有队列绑定的exchange上面,那么该消息将会丢失,这是因为在rabbitMQ中exchange不具备存储消息的能力,只有队列具备存储消息的能力。

    关于队列、exchange:

    无论哪一种广播类型,发布者都无需要声明和指定队列,而是声明和指定exchange,同时指定广播类型。

    无论哪一种广播类型,订阅者都需要使用系统随机分配的队列(可以确保唯一性,如果自定义的queue可能重名)来接收消息,并将队列绑定到exchange;同时声明和指定exchange,同时指定广播类型。

    关于routing_key:

    routing_key,即路由的标识符,可以为任意字符;也可以使用队列名作为标识符,但它本身的含义不是队列名。

    不同类型的广播,区别在于exchange_type不同,使得不同类型的routing_key不同。

    • fanout类型,发布者无需要指定routing_key。
    • direct类型,发布者需要指定routing_key,订阅者使用相同的routing_key匹配,就像分组一样。
    • topic类型,发布者需要指定routing_key,订阅者可使用带通配符的routing_key去匹配,是比分组更精细的匹配。

    不同的 Exchange 会表现出不同路由行为。Durable 是该 Exchange 的持久化属性。声明一个 Binding 需要提供一个 QueueName、Exc

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值