Skip to content

Rabbitmq

RabbitMQ是一个开源的、实现了高级消息队列协议(AMQP, Advanced Message Queuing Protocol)的消息中间件(Message Broker)。它使用Erlang语言开发,这门语言以其在构建高并发、高可靠性、分布式系统方面的优势而闻名,因此RabbitMQ天生就具备了很好的稳定性和性能。

简单来说,RabbitMQ就像一个现实生活中的邮局。生产者(Producer)将消息(信件)发送到邮局,邮局(RabbitMQ)根据规则(路由规则)将信件投递到不同的邮箱(队列),最终由消费者(Consumer)从邮箱中取出并处理信件。它的核心作用是应用解耦、异步处理和流量削峰。

核心组件

  1. Producer (生产者):发送消息的应用程序。

  2. Consumer (消费者):接收并处理消息的应用程序。

  3. Broker: 指的是RabbitMQ服务本身,它接收来自生产者的消息,并将其路由给消费者。

  4. Queue (队列):位于RabbitMQ内部,用于存储消息的缓冲区,类似于邮箱。消息最终被投递到这里,等待消费者来获取。队列可以有多个消费者,消息会以轮询(Round-robin)的方式分发给它们。

  5. Exchange (交换机):这是RabbitMQ中非常重要的一个概念,它接收来自生产者的消息,并根据特定的规则将消息路由到一个或多个队列中。交换机本身不存储消息,它只是一个路由中转站。

  6. Binding (绑定):定义了Exchange和Queue之间的关联关系。一个绑定就是一条规则,它告诉交换机如何将消息路由到指定的队列。绑定通常会附带一个Routing Key

标准工作流程如下

  1. 生产者将消息发送给一个指定的Exchange。发送时,通常会附带一个Routing Key。

  2. Exchange收到消息后,会查找所有与自己绑定的Queue。

  3. 根据Exchange的类型和消息的Routing Key,与每个Queue绑定的Binding Key进行匹配。

  4. 如果匹配成功,Exchange就会将消息的一份拷贝放入对应的Queue中。

  5. 消费者监听某个Queue,当Queue中有消息时,就会接收并进行处理。

Exchange的四种主要类型

  • Direct Exchange (直连交换机):它会把消息路由到那些Binding Key与Routing Key完全匹配的队列中。这是最简单直接的匹配方式。

  • Fanout Exchange (扇形交换机):它会忽略Routing Key,将接收到的所有消息广播到所有与其绑定的队列中。非常适合做“发布/订阅”模式,比如系统通知广播。

  • Topic Exchange (主题交换机):这是最灵活的一种。它支持使用通配符来匹配Routing Key和Binding Key。* (星号)可以替代一个单词,# (井号)可以替代零个或多个单词。例如,一个Routing Key为 log.error.database 的消息,可以被 log.error.*log.# 的Binding Key匹配到。

  • Headers Exchange (头交换机):不依赖于Routing Key进行匹配,而是根据消息头(Headers)中的键值对来进行匹配。性能上相对较差,使用场景不多。

可靠性保障

RabbitMQ不仅仅是简单地传递消息,它还提供了一系列机制来保证消息处理的可靠性。

  1. 消息持久化:为了防止RabbitMQ服务器宕机导致消息丢失,我们可以将Exchange、Queue和消息本身都设置为持久化(Durable)。这样,即使服务重启,相关的配置和消息也能恢复。

  2. 消费确认机制 (Acknowledgements, ack):默认情况下,当RabbitMQ将消息推送给消费者后,会立即在队列中删除该消息。但如果此时消费者进程异常退出,消息就会丢失。为了解决这个问题,可以开启手动ack模式。消费者在成功处理完消息后,会向RabbitMQ发送一个ack回执,此时RabbitMQ才会真正删除消息。如果消费者在处理过程中断开连接(或发送nack),RabbitMQ会认为消息没有被成功处理,并将其重新投递给其他消费者。

  3. 生产者确认机制 (Publisher Confirms):为了保证消息从生产者可靠地到达RabbitMQ服务器,可以开启Publisher Confirms模式。开启后,生产者发送的每条消息都会被分配一个唯一ID,当消息被RabbitMQ成功接收后,RabbitMQ会回调生产者的一个接口,告知消息已成功送达。如果消息在网络中丢失或RabbitMQ内部出错,生产者就无法收到确认,从而可以进行重发。

  4. 高可用性

    • 集群 (Clustering):可以将多个RabbitMQ节点组成一个集群,所有节点共享元数据(队列、交换机、用户等信息)。客户端可以连接到集群中的任意节点。但这并不能保证队列中消息的高可用,因为默认情况下,队列及其内容只存在于创建它的那个节点上。

    • 镜像队列 (Mirrored Queues):为了解决单点故障问题,可以在集群的基础上配置镜像队列。一个镜像队列会有一个主节点(Master)和若干个从节点(Slave)。所有发送到主节点的消息都会被自动复制到所有从节点。当主节点宕机后,最老的从节点会自动提升为新的主节点,从而保证服务的连续性和消息的可用性。