Rabbit入门之Rabbit架构和Rabbit的五种模式

27 阅读6分钟

Rabbit架构

Rabbit架构如下图所示: 6df51a4a3917e48bf3919efcc3fd3ff.png

图中包含几个概念:

  • 生产者(Producer) : 用来生产与发送消息的角色
  • 消费者(Consumer) : 接收并处理消息的角色。
  • 代理(Broker) : 中间件服务器,负责接收生产者的消息,根据路由规则将其存储或转发给一个或多个消费者。
  • 队列(Queue) : 消息的存储位置,是消息被消费前的临时存放点。
  • 交换机(Exchange) : 负责将消息路由到一个或多个队列的组件。
  • 虚拟主机(VirtualHost): 虚拟主机,具备隔离效果的一个空间

RabbitMQ的五种模式

1.简单模式【Hello World!】

image.png

简单模式下一个消费者对应一个生产者

  • publisher直接发送消息到队列
  • 消费者监听并处理队列中的消息

使用场景:实际工作中基本用不到

2.工作队列模式【Work Queues】

image.png

Work Queues:工作队列模式下一个生产者对应多个消费者。也叫公平分配队列或能者多劳消息队列

  • 公平分配:消息平均分配给每个消费者,即使消费者处理完消息也不能获取更多消息
  • 能者多劳:消费者之间处于竞争关系,消费者处理完消息就能接收下一条

场景:12306的短信服务。

开启能者多劳所需的配置:

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

3.发布订阅模式【Publish/Subscribe】

image.png

Publish/Subscribe:一条消息能被多个消费者订阅。发布订阅模式加入了 Exchange(交换机) 这个角色,一旦加入了交换机这个角色,生产者的消息就不再发给队列了,而是发给交换机,再由交换机根据规则路由到队列里面。

  • 交换机类型为 fanout:表示为扇出,其实就是无条件群发,此时每个消费者都能接收到消息。

场景:适用于数据大规模分发的情况。中国气象局提供气象信息,腾讯,网易拿到相同的气象信息。

4.路由模式【Routing】

image.png

Routing:是发布订阅模式的变种。交换机根据routingKey有条件将数据筛选后发给消费者队列。

  • 交换机类型为Direct:订阅,基于RoutingKey(路由key)发送给订阅了消息的队列
  • routingKey :路由Key 是一个字符串,用于在消息发布时指定消息的路由信息。

在Direct模型下:

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
  • 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey
  • Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息 场景:日志。消费者是监控系统,error的错误日志就会放到消费者队列中。

5.Topic模式【Topics】

image.png

Topics:Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。 只不过Topic类型Exchange可以让队列在绑定BindingKey 的时候使用通配符

  • 交换机类型为Topic:通配符订阅,与Direct类似,只不过RoutingKey可以使用通配符

  • 通配符规则

    • #:匹配一个或多个词
    • *:匹配不多不少恰好1个词
  • 举例:

    • item.#:能够匹配item.spu.insert 或者 item.spu
    • item.*:只能匹配item.spu

四种交换机

交换机的类型有四种:

  • Direct:订阅,基于RoutingKey(路由key)发送给订阅了消息的队列
  • Fanout:广播,将消息交给所有绑定到交换机的队列。我们最早在控制台使用的正是Fanout交换机
  • Topic:通配符订阅,与Direct类似,只不过RoutingKey可以使用通配符
  • Headers:头匹配,基于MQ的消息头匹配,用的较少。

1. 直接交换机(Direct Exchange)

  • 定义:直接交换机会将消息路由到与消息的 routingKey 完全匹配的队列。

  • 工作原理

    • 生产者发送消息时指定一个 routingKey
    • 队列通过带有特定 bindingKey 的绑定连接到直接交换机。
    • 只有当消息的 routingKey 与队列的 bindingKey 完全一致时,该消息才会被投递到对应的队列中。

示例

假设有一个直接交换机 direct_exchange 和两个队列 queue1queue2,其中:

  • queue1 绑定到 direct_exchange 交换机,并设置 bindingKey 为 info
  • queue2 绑定到同一个交换机,但其 bindingKey 为 error

如果生产者向 direct_exchange 交换机发送一条消息,并且设置了 routingKeyinfo,那么这条消息只会被发送到 queue1。同样地,如果消息的 routingKeyerror,则它会被发送到 queue2

2. 扇出交换机(Fanout Exchange)

  • 定义:扇出交换机会将消息广播到所有绑定到它的队列,忽略 routingKey

  • 工作原理

    • 扇出交换机不关心 routingKey,它会将消息发送到所有绑定到它的队列。
    • 适用于需要将消息广播给多个消费者的场景。

示例

假设有一个扇出交换机 fanout_exchange 和两个队列 queue1queue2,它们都绑定到 fanout_exchange 交换机。

如果生产者向 fanout_exchange 交换机发送一条消息,无论 routingKey 是什么,这条消息都会被广播到 queue1queue2

3. 主题交换机(Topic Exchange)

  • 定义:主题交换机会根据 routingKey 和通配符进行模糊匹配来路由消息。

  • 工作原理

    • routingKey 通常由点号(.)分隔的单词组成。

    • 队列可以使用两种通配符来匹配 routingKey

      • *:匹配一个词。
      • #:匹配零个或多个词。

示例

假设有一个主题交换机 topic_exchange 和三个队列 queue1queue2queue3,其中:

  • queue1 绑定到 topic_exchange 交换机,并设置 bindingKey 为 *.orange.*
  • queue2 绑定到同一个交换机,但其 bindingKey 为 lazy.#
  • queue3 绑定到同一个交换机,但其 bindingKey 为 #.rabbit

如果生产者向 topic_exchange 交换机发送一条消息,并且设置了 routingKeylazy.orange.rabbit,那么这条消息将会被路由到 queue1queue2。如果 routingKeyquick.orange.fox,那么消息会被路由到 queue1。如果 routingKeylazy.brown.fox,那么消息会被路由到 queue2

4. 头部交换机(Headers Exchange)

  • 定义:头部交换机会根据消息头中的属性来进行路由,而不是 routingKey

  • 工作原理

    • 头部交换机忽略 routingKey,而是根据消息头中的属性进行匹配。
    • 队列可以绑定到头部交换机并指定一组键值对,只有当消息头中的属性完全匹配这些键值对时,消息才会被路由到相应的队列。

示例

假设有一个头部交换机 headers_exchange 和两个队列 queue1queue2,其中:

  • queue1 绑定到 headers_exchange 交换机,并设置绑定参数为 x-match: all, header1: value1, header2: value2
  • queue2 绑定到同一个交换机,但其绑定参数为 x-match: any, header1: value1, header3: value3

如果生产者向 headers_exchange 交换机发送一条消息,并且设置了消息头为 header1: value1, header2: value2,那么这条消息会被路由到 queue1。如果消息头为 header1: value1, header3: value3,那么消息会被路由到 queue2