RabbitMQ交换机与队列研究

一、交换机

交换机主要包括如下4种类型:
Direct exchange(直连交换机)
Fanout exchange(扇型交换机)
Topic exchange(主题交换机)
Headers exchange(头交换机)

另外RabbitMQ默认定义了一些交换机:
默认交换机
amq.* exchanges

还有一类特殊的交换机:Dead Letter Exchange(死信交换机)

1.1 Direct exchange(直连交换机)

将消息的routing key与队列的binding key进行精确匹配,匹配上则发送到相应队列,可以发送到多个队列,若无匹配,则转发队列失败。

1.2 Fanout exchange(扇型交换机)

将消息发送到所有队列,不会计算消息的routing key与队列的binding key是否匹配。

1.3 Topic exchange(主题交换机)

将消息的routing key与队列的binding key进行模糊匹配,匹配上则发送到相应队列,可以发送到多个队列,若无匹配,则转发队列失败。

binding key支持*和#,*只能匹配一个词,#可以匹配多个词。

例如:
order.*可以匹配order.123456,不能匹配order.cancel.123456
order.#可以匹配order.123456order.cancel.123456

说明:以上例子order.*是binding key,order.123456是routing key

1.4 Headers exchange(头交换机)

不处理路由键,而是根据发送的消息内容中的headers属性进行匹配。在绑定Queue与Exchange时指定一组键值对;当消息发送到RabbitMQ时会取到该消息的headers与Exchange绑定时指定的键值对进行匹配;如果完全匹配则消息会路由到该队列,否则不会路由到该队列。headers属性是一个键值对,可以是HashTable,键值对的值可以是任何类型。而fanout,direct,topic 的路由键都需要要字符串形式的。

匹配规则x-match有下列两种类型:
x-match = all :表示所有的键值对都匹配才能接受到消息
x-match = any :表示只要有键值对匹配就能接受到消息

1.5 其它交换机

在RabbitMQ默认定义一些交换机,主要如下:

1.5.1 默认交换机

默认交换机(default exchange)实际上是一个由RabbitMQ预先声明好的名字为空字符串的直连交换机(direct exchange)。它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称与队列名称相同。

如:当你声明了一个名为”hello”的队列,RabbitMQ会自动将其绑定到默认交换机上,绑定(binding)的路由键名称也是为”hello”。因此,当携带着名为”hello”的路由键的消息被发送到默认交换机的时候,此消息会被默认交换机路由至名为”hello”的队列中。即默认交换机看起来貌似能够直接将消息投递给队列,如同我们之前文章里看到一例子。

1.5.2 amq.*的名称的交换机

这些是RabbitMQ默认创建的交换机。这些队列名称被预留做RabbitMQ内部使用,不能被应用使用,否则抛出403 (ACCESS_REFUSED)错误

1.5.3 Dead Letter Exchange(死信交换机)

在默认情况,如果消息在投递到交换机时,交换机发现此消息没有匹配的队列,则这个消息将被悄悄丢弃。为了解决这个问题,RabbitMQ中有一种交换机叫死信交换机。当消费者不能处理接收到的消息时,将这个消息重新发布到另外一个队列中,等待重试或者人工干预。这个过程中的exchange和queue就是所谓的”Dead Letter Exchange 和 Queue”

1.5.4 交换机的属性

除交换机类型外,在声明交换机时还可以附带许多其他的属性,其中最重要的几个分别是:

Name:交换机名称
Durability:是否持久化。如果持久性,则RabbitMQ重启后,交换机还存在
Auto-delete:当所有与之绑定的消息队列都完成了对此交换机的使用后,删掉它
Arguments:扩展参数

二、队列

队列绑定到交换机上,可以设置一个binding key,也可以不设置。

  • 当不设置binding key时,若队列绑定到直连交换机或主题交换机,那么生产者发送消息时不设置routing key,才能收到消息。

  • 当设置binding key时,若队列绑定到直连交换机或主题交换机,那么生产者发送消息时需要设置routing key,且被binding key匹配上,才能收到消息。

  • 当队列绑定到扇形交换机,队列的binding key与消息的routing key无效,不管队列是否设置binding key和生产者是否设置routing key,生产者发送到扇形交换机的消息,队列都能收到。

三、消费者

消费者绑定到某个队列上,当有多个消费者绑定同一队列时,会使用轮循的方式将消息分发给各消费者。

四、生产者

生产者往交换机发送消息,可附带一个routing key,也可以不带。

  • 发送消息到直连交换机时,不带routing key,消息只会转发到未设置binding key的队列;带了routing key,消息只会转发到设置了相同binding key的队列。

  • 发送消息到扇形交换机时,带不带routing key,消息都会转发给所有队列。

  • 发送消息到主题交换机时,不带routing key,消息只会转发到未设置binding key的队列;带了routing key,消息会按照routing key转发被binding key匹配的队列。一般binding key是一个模糊匹配表达式(如:order.*,order.#),routing key是一个精确值(如:order.123456,order.cancel.123456)

参考资料

  1. 中间件系列三 RabbitMQ之交换机的四种类型和属性

你可能感兴趣的:(系统架构,rabbitmq,exchange)