RabbitMQ实战指南之RabbitMQ架构及运转流程

相关概念

RabbitMQ 整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。可以把消息传递的过程想象成∶ 当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ 就好比由邮局、邮箱和邮递员组成的一个系统。从计算机术语层面来说, RabbitMQ 模型更像是一种交换机模型。RabbitMQ 的整体模型架构如所示。
在这里插入图片描述

生产者和消费者

Producer∶ 生产者,就是投递消息的一方。

生产者创建消息,然后发布到 RabbitMQ 中。消息一般可以包含 2 个部分∶消息体和标签(Label)。消息体也可以称之为 payload,在实际应用中,消息体一般是一个带有业务逻辑结构的数据,比如一个 JSON 字符串。当然可以进一步对这个消息体进行序列化操作。

消息的标签用来表述这条消息,比如一个交换器的名称和一个路由键。生产者把消息交由RabbitMO, RabbitMQ 之后会根据标签把消息发送给感兴趣的消费者(Consumer)。

Consumer∶ 消费者,就是接收消息的一方。

消费者连接到 RabbitMQ 服务器,并订阅到队列上。当消费者消费一条消息时,只是消费消息的消息体(payload)。在消息路由的过程中,消息的标签会丢弃,存入到队列中的消息只有消息体,消费者也只会消费到消息体,也就不知道消息的生产者是谁,当然消费者也不需要知道。

Broker∶ 消息中间件的服务节点。

对于RabbitMQ来说,一个RabbitMQ Broker 可以简单地看作一个 RabbitMQ 服务节点,或者 RabbitMQ服务实例。大多数情况下也可以将一个 RabbitMQ Broker看作一台RabbitMQ服务器。

在这里插入图片描述

首先生产者将业务方数据进行可能的包装,之后封装成消息,发送(AMQP 协议里这个动作对应的命令为Basic.Publish)到 Broker 中。消费者订阅并接收消息(AMQP协议里这个动作对应的命令为Basic.Consume或者Basic.Get),经过可能的解包处理得到原始的数据,之后再进行业务处理逻辑。这个业务处理逻辑并不一定需要和接收消息的逻辑使用同一个线程。消费者进程可以使用一个线程去接收消息,存入到内存中,比如使用 Java中的BlockingQueue。业务处理逻辑使用另一个线程从内存中读取数据,这样可以将应用进一步解耦,提高整个应用的处理效率。

队列

Queue∶ 队列,是 RabbitMQ 的内部对象,用于存储消息
在这里插入图片描述

RabbitMQ中消息都只能存储在队列中,这一点和Kafka这种消息中间件相反。Kafka 将消息存储在 topic(主题)这个逻辑层面,而相对应的队列逻辑只是 topic 实际存储文件中的位移标识。RabbitMQ 的生产者生产消息并最终投递到队列中,消费者可以从队列中获取消息并消费。
多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin,即轮询)给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理,如图。
在这里插入图片描述

RabbitMQ 不支持队列层面的广播消费,如果需要广播消费,需要在其上进行二次开发,处理逻辑会变得异常复杂,同时也不建议这么做。

交换器、路由键、绑定

Exchange∶ 交换器。

在上面图中我们暂时可以理解成生产者将消息投递到队列中,实际上这个在 RabbitMQ 中不会发生。真实情况是,生产者将消息发送到 Exchange(交换器,通常也可以用大写的"X"来表示),由交换器将消息路由到一个或者多个队列中。如果路由不到,或许会返回给生产者,或许直接丢弃。
交换器的具体示意图下图所示。
在这里插入图片描述

RabbitMQ中的交换器有四种类型:

  • fanout
  • direct
  • topic
  • headers

不同的类型有着不同的路由策略。

RoutingKey∶ 路由键

生产者将消息发给交换器的时候,一般会指定一个 RoutingKey,用来指定这个消息的路由规则,而这个 Routing Key 需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效。
在交换器类型和绑定键(BindingKey)固定的情况下,生产者可以在发送消息给交换器时,通过指定 RoutingKey 来决定消息流向哪里。

Binding∶ 绑定

RabbitMQ 中通过绑定将交换器与队列关联起来,在绑定的时候一般会指定一个绑定键(BindingKey),这样 RabbitMQ 就知道如何正确地将消息路由到队列了
在这里插入图片描述

RabbitMQ运转流程

了解了以上RabbitMQ模型,回顾一下RabbitMQ的运转流程如下:

生产者发送消息

  1. 生产者连接到 RabbitMO Broker,建立一个连接(Connection),开启一个信道(Channel)。
  2. 生产者声明一个交换器,并设置相关属性,比如交换机类型、是否持久化等。
  3. 生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等。
  4. 生产者通过路由键将交换器和队列绑定起来。
  5. 生产者发送消息至 RabbitMO Broker,其中包含路由键、交换器等信息。
  6. 相应的交换器根据接收到的路由键查找相匹配的队列。
  7. 如果找到,则将从生产者发送过来的消息存入相应的队列中。
  8. 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者。
  9. 关闭信道。
  10. 关闭连接。

消费者接收消息

  1. 消费者连接到 RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)。
  2. 消费者向 RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数,以及做一些准备工作
  3. 等待 RabbitMQ Broker 回应并投递相应队列中的消息,消费者接收消息。
  4. 消费者确认(ack)接收到的消息。
  5. RabbitMQ 从队列中删除相应已经被确认的消息。
  6. 关闭信道。

参考文章
博客整理自《RabbitMQ实战指南》

Guess you like

Origin blog.csdn.net/crazyjack1/article/details/119089832